签名算法

签名算法

接口需要签名的地方,均采用如下的算法,KEY(根据接口而定,可能是APP_KEY或APP_SECRET)由平台分配:

  1. 所有不为空、不为0的参数都需要加入签名,参数必须为 urlencode 之前的原始数值。如参数中文,作为参数传输时编码为%e4%b8%ad%e6%96%87,签名计算时则要用其原始值中文(注意字符集必须是 UTF-8)
  2. 对所有待签名参数,按照参数名字母升序排列(如php的ksort函数、Java的TreeMap等)。
  3. 使用符号#拼装排序后的参数值,最后用#连接KEY,得到签名文本。
  4. 对签名文本进行MD5计算,就是sign参数的值。MD5值32位小写

签名算法示例代码:

public String getSignature(String key){
	TreeMap<String,String> paramsMap = new TreeMap<>();
    paramsMap.put("channelId", String.valueOf(channelId));
    paramsMap.put("timestamp", String.valueOf(timestamp));
    paramsMap.put("", "");  // 其他参数
    paramsMap.put("", "");  // 其他参数
    paramsMap.put("", "");  // 其他参数

    StringBuilder sb = new StringBuilder();
    String pound = "";
    for(String val : paramsMap.values()){
        if(val == null || trim().length() = 0 || val.equals("0")){
            continue;
        }
        sb.append(pound).append(val);
        pound = "#";
    }
    sb.append(pound).append(key);
    // MD5算法
    return DigestUtils.md5Hex(sb.toString());
}
const md5Hex = text => {
    // console.log(text)
    return md5.md5(text)
}

const genSign = data => {
    let keys = Object.keys(data).sort()
    let values = []
    for (let k of keys) {
        let v = data[k]
        if (!v || v === '0') {
            continue
        }
        values.push(v)
    }
    values.push(AppKey)
    return md5Hex(values.join('#'))
}

// 公共属性赋值并签名
const encryptData = data => {
    data.appId = AppId
    data.ts = Math.floor(new Date().getTime()/1000)
    data.sign = genSign(data)
    return data
}

请求内容:

https://xxx.66hjh.com/xxx/xxx?channel=1001&timestamp=1560313550&appId=1&sign=8237e0b5622a8cdea94e8955ba998f90

签名拼接字符串:

// 签名密钥为 KEY
1#1001#1560313550#KEY

MD5后的值:

9ce90e921ca4f016420c11a6c28b790f