我們在日常編程中總會遇到各種簽名算法,今天總結一下常用簽名加密MD5,Base64,SHA1,HMAC.....
-
在簽名之前我們通常會把參數排序,下面先列舉2種排序方法:
/**
* 簽名排序一( ASCII 碼從小到大排序(字典序))
*
* @param map
* @return
*/
public static String sortMapKey(Map<String, String> map) {
//將map放入到List中
List<Map.Entry<String, String>> infoIds = new ArrayList<>(map.entrySet());
//排序
infoIds.sort(Comparator.comparing(o -> (o.getKey())));
// 構造URL 鍵值對的格式
StringBuilder buf = new StringBuilder();
//循環構建鍵值對字符串
for (Map.Entry<String, String> item : infoIds) {
if (StringUtils.isNotBlank(item.getKey())) {
String key = item.getKey();
String val = item.getValue();
buf.append(key).append("=").append(val);
buf.append("&");
}
}
String buff = buf.toString();
if (!buff.isEmpty()) {
buff = buff.substring(0, buff.length() - 1);
}
return buff;
}
/**
* 簽名排序二(字母順序)
* @param requestParam
* @return
*/
public static String formPublicParam(Map<String, String> requestParam) {
//所有的參數,這裏使用TreeMap, 好處在於天然有序,默認是字母順序
Map<String, String> params = new TreeMap<>();
params.putAll(requestParam);
//訪問的URL
StringBuffer buffer = new StringBuffer();
for (Map.Entry<String, String> param : params.entrySet()) {
buffer.append(param.getKey() + "=" + param.getValue());
}
return buffer.toString();
}
2.下面列舉各種簽名加密方式:
/**
* MD5簽名
*
* @param map
* @return
*/
public static String sign(Map<String, String> map) {
//排序
String params = sortMapKey(map);
//調用md5簽名
return DigestUtils.md5DigestAsHex(params.getBytes());
}
/**
* 驗證簽名
*
* @param map
* @param test
* @return
*/
public static boolean verification(Map<String, String> map, String test) {
String sign = sign(map);
return sign.equals(test);
}
/**
* SHA1安全加密算法
*
* @parammaps參數key-valuemap集合
* @return
* @throwsDigestException
*/
public static String shaSign(Map<String, String> maps) throws DigestException {
//獲取信息摘要-參數排序後字符串
String decrypt = sortMapKey(maps);
try {
//指定sha1算法
MessageDigest digest = MessageDigest.getInstance("SHA-1");
//Updates the digest using the specified array of bytes.
digest.update(decrypt.getBytes());
//獲取字節數組
byte messageDigest[] = digest.digest();
//CreateHexString
StringBuffer hexString = new StringBuffer();
//字節數組轉換爲十六進制數
for (int i = 0; i < messageDigest.length; i++) {
String shaHex = Integer.toHexString(messageDigest[i] & 0xFF);
if (shaHex.length() < 2) {
hexString.append(0);
}
hexString.append(shaHex);
}
return hexString.toString().toUpperCase();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
throw new DigestException("簽名錯誤!");
}
}
/**
* base64加密
*
* @param params
* @return
*/
private static String base64Encode(Map<String, String> params) {
String key = sortMapKey(params);
// 加密
BASE64Encoder encoder = new BASE64Encoder();
String encode = encoder.encode(key.getBytes());
return encode;
}
/**
* base64解密
*
* @param encode
* @return
*/
private static String base64Decoder(String encode) {
// 解密
BASE64Decoder decoder = new BASE64Decoder();
String decode = null;
try {
decode = new String(decoder.decodeBuffer(encode));
} catch (IOException e) {
e.printStackTrace();
throw new MyException(e.getMessage());
}
return encode;
}
public static final String KEY_MAC = "HmacMD5";
/**
* HmacMD5算法簽名
*/
public static String getHmacMD5Sign(Map<String, String> requestParam, String key) {
String data = sortMapKey(requestParam);
byte[] inputData = data.getBytes();
SecretKey secretKey = new SecretKeySpec(key.getBytes(), KEY_MAC);
Mac mac;
try {
mac = Mac.getInstance(secretKey.getAlgorithm());
mac.init(secretKey);
return byteArrayToHexString(mac.doFinal(inputData));
} catch (Exception e) {
throw new MyException("HmacMD5算法加密失敗" + e.getMessage());
}
}
/**
* byte數組轉換爲String
* @param b
* @return
*/
private static String byteArrayToHexString(byte[] b) {
StringBuffer sb = new StringBuffer(b.length * 2);
for (int i = 0; i < b.length; i++) {
int v = b[i] & 0xff;
if (v < 16) {
sb.append('0');
}
sb.append(Integer.toHexString(v));
}
return sb.toString();
}
請仔細閱讀代碼註釋哦,所有信息基本都註釋了