跳至主要内容

2- 2、如何簽名

簽章(簽章校驗皆可適用)

簽名產生的通用步驟如下:

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&notifyUrl=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 + "]";
}

private static String getListConstable(List<?> list) {
List<String> l = new ArrayList<>();
list.forEach(item -> {
l.add( String.valueOf(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;
if (list.isEmpty()) return;
if(list instanceof Map<?,?>){
s = getListString((List<Map<String, Object>>) list);
}else{ s = getListConstable(list);}
}else if (value instanceof Map){
s = "{" + getString( (Map<String, Object>) value ) + "}";
}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());
}