二、如何签名
签名
签名生成的通用步骤如下::
MD5 加密 需要进行 utf-8 编码
第一步、设所有发送或者接收到的数据为集合 M,将集合 M 内非空参数值的参数按照参数名 ASCII 码从小到大排序(字典序),使用 URL 键值对的格式(即 key1=value1&key2=value2…)拼接成得到字符串 stringA。
第二步、在 stringA 最后拼接上应用 secret 得到 stringSignTemp 字符串,并对 stringSignTemp 进行 MD5 运算,得到 sign 值 signValue。
签名字符串示例:key=08SaKUwNafSOc8w7&localOrderId=2023102400684344447&localUserId=302199873005¬ifyUrl=http://127.0.0.1:8080/call-back/demo/notify&secret=uRdLM5BeMobQ4SePrwqZd35lNXyXJUHh
第三步、MD5 加密:MD5(待签名字符串)
得到签名 sign: 6416c9f6eb37c8a901904026c769bec0(小写)
----java签名代码工具
private static String getListString(List<Map<String, Object>> list) {
List<String> l = new ArrayList<>();
list.forEach(item -> {
l.add(getString(item));
});
String arrStr = String.join(",", l);
return "[" + arrStr + "]";
}
public static String getString(Map<String, Object> p) {
List<String> query = new ArrayList<>();
p.entrySet().stream().sorted(Map.Entry.comparingByKey()).forEach((v) -> {
String s;
Object value = v.getValue();
if( value == null ) return ;
if (value instanceof List<?>) {
List<?> list = (List<?>) value;
s = getListString((List<Map<String, Object>>) list);
} else if (value instanceof Double) {
Double doubleValue = (Double) value;
s = new BigDecimal(String.valueOf(doubleValue)).stripTrailingZeros().toPlainString();
} else if (value instanceof Float) {
Float floatValue = (Float) value;
s = new BigDecimal(String.valueOf(floatValue)).stripTrailingZeros().toPlainString();
} else if (value instanceof BigDecimal) {
BigDecimal bigDecimalValue = (BigDecimal) value;
s = bigDecimalValue.stripTrailingZeros().toPlainString();
} else {
s = value.toString();
}
query.add(v.getKey() + "=" + s);
});
return String.join("&", query);
}
public static String getSignStr(Map<String, Object> p, String secret){
return getString(p) + "&secret=" + secret;
}
public static String getSign(Map<String, Object> p, String secret) {
if (p.isEmpty()) return "";
String originalSign = getSignStr(p, secret);
log.info("待签名字符串 {}", originalSign);
return DigestUtils.md5DigestAsHex(originalSign.getBytes());
}