签名方式实例

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; } ```