签名方式实例
1、签名算法
签名生成的通用步骤如下:
第一步,设所有发送或者接收到的数据为集合M,将集合M内非空参数值的参数按照参数名ASCII码从小到大排序(字典序),使用URL键值对的格式(即key1=value1&key2=value2…)拼接成字符串stringA。
特别注意以下重要规则:
◆ 参数名ASCII码从小到大排序(字典序);
◆ 如果参数的值为空不参与签名;
◆ 参数名区分大小写;
◆ 验证调用返回或合豚主动通知签名时,传送的sign参数不参与签名,将生成的签名与该sign值作校验。
◆ 接口可能增加字段,验证签名时必须支持增加的扩展字段
第二步,在stringA最后拼接上key得到str字符串,并对进行 `md5` 运算,再将得到的字符串所有字符转换为大写,得到sign值signValue。
举例:
假设传送的参数如下:
appid: 20206511234
body: test
nonce_str: ibuaiVcKdpRxkhJA
第一步:对参数按照key=value的格式,并按照参数名ASCII字典序排序如下:
stringA="appid=wxd930ea5d5a258f4f&body=test&device_info=1000&nonce_str=ibuaiVcKdpRxkhJA";
第二步:拼接API密钥:
str=stringA+"&key=dsfavnhkytsdf234" //注:key为商户设置的密钥key
sign=md5(str,key).toUpperCase()="6A9AE1657590FD6257D6" //注:MD5签名方式
## 签名生成MD5算法
### java
```java
/**
* 生成签名. 注意,若含有sign_type字段,必须和signType参数保持一致。
*
* @param data 待签名数据
* @param key API密钥
* @return 签名
*/
public static String generateSignature(final Map<String, Object> data, String key) throws Exception {
Set<String> keySet = data.keySet();
String[] keyArray = keySet.toArray(new String[keySet.size()]);
Arrays.sort(keyArray);
StringBuilder sb = new StringBuilder();
for (int i = 0; i < keyArray.length; i++) {
if (data.get(keyArray[i]) != null) {
sb.append(keyArray[i]).append("=").append(data.get(keyArray[i]));
if (i != keyArray.length - 1) {
sb.append("&");
}
}
}
sb.append("&key=" + key);
String sign = sb.toString();
return MD5(sign);
}
/**
* 生成 MD5
*
* @param data 待处理数据
* @return MD5结果
*/
public static String MD5(String data) throws Exception {
MessageDigest md = MessageDigest.getInstance("MD5");
byte[] array = md.digest(data.getBytes("UTF-8"));
StringBuilder sb = new StringBuilder();
for (byte item : array) {
sb.append(Integer.toHexString((item & 0xFF) | 0x100).substring(1, 3));
}
return sb.toString().toUpperCase();
}
```
### nodejs / typescirpt
```javascript
/**
* 生成签名. 注意,若含有sign_type字段,必须和signType参数保持一致。
*
* @param params 待签名数据
* @param key API密钥
* @return 签名
*/
public generateSign(params: any, key: string): string {
const signStr = `${this.sortParams(params)}&key=${key}`;
console.log("signStr", signStr);
const md5 = crypto.createHash("md5");
md5.update(signStr);
return md5.digest("hex").toUpperCase();
}
// 排序参数
sortParams(args) {
let keys = Object.keys(args);
keys = keys.sort();
const newArgs = {};
keys.forEach((key) => {
newArgs[key] = args[key];
});
let string = "";
for (const k in newArgs) {
string += "&" + k + "=" + newArgs[k];
}
string = string.substr(1);
return string;
}
```