一、参数按照KEY值进行字典序排序(按照KEY值的ASCII码从小到大),并用&作为各参数之间的分隔符将参数拼接成字符串。这里用到了SortedMap。
/**
* getSortedString 对参数按照Key进行ASCII排序
* @param jsonObject 请求参数
* @return 排序拼装后的字符串
*/
public static String getSortedString(JSONObject jsonObject){
SortedMap<String,Object> sortMap = new TreeMap<>();
StringBuffer sbf = new StringBuffer();
for (Map.Entry<String, Object> objectEntry : jsonObject.entrySet()) {
String key = objectEntry.getKey();
Object value = objectEntry.getValue();
if ("sign".equals(key)){
continue;
}
sortMap.put(key,value);
}
Set mapEntrySet = sortMap.entrySet();
Iterator it = mapEntrySet.iterator();
while(it.hasNext()){
Map.Entry entry = (Map.Entry)it.next();
String k = (String) entry.getKey();
Object v = entry.getValue();
sbf.append(k+"="+v+"&");
}
String sbfString = sbf.toString();
System.out.println("排序后的字符串:"+sbfString.substring(0,sbfString.length()-1));
return sbfString.substring(0,sbfString.length()-1);
}
二、生成签名方法
/**
* sha256_HMAC加密
* @param data 数据
* @param secret 秘钥
* @return 加密后字符串
*/
private static String sha256_HMAC(String data, String secret) {
String sign = "";
Base64Tools base64Tools = new Base64Tools();
try {
Mac sha256_HMAC = Mac.getInstance("HmacSHA256");
//秘钥base64解码
String keyBytes = base64Tools.decodeStr(secret);
SecretKeySpec secret_key = new SecretKeySpec(keyBytes.getBytes(StandardCharsets.UTF_8), "HmacSHA256");
sha256_HMAC.init(secret_key);
byte[] bytesSign = sha256_HMAC.doFinal(data.getBytes(StandardCharsets.UTF_8));
sign = byteArrayToHexString(bytesSign);
} catch (Exception e) {
logger.error("生成签名错误:"+e.getMessage(),e);
}
return sign;
}
三、验签方法
/**
* checkSign 验签
* @param data 数据
* @param secret 秘钥
* @param signature 校验的签名
* @return 校验结果
*/
public static boolean checkSign(String data, String secret, String signature) {
//true:校验成功
String getSign = sha256_HMAC(data, secret);
return signature != null && signature.equals(getSign);
}
四、测试生成签名
public static void main(String[] args) {
String data = "{\n" +
" \"appid\": \"WXTX\",\n" +
" \"tel\": \"18888888888\",\n" +
" \"timestamp\": \"1617334523\"\n" +
"}";
JSONObject jsonObject = JSONObject.parseObject(data);
//对参数进行排序
String sortData = getSortedString(jsonObject);
String secret = "TjNCMkFGQzAzNTA0RTZTTUUwNTM3QzBBQjhDMDc5ODg=";
System.out.println("生成签名:"+sha256_HMAC(sortData,secret));
}