以下的签名校验只是我和团队商议的一种做法,仅供自己参考。思想无非就是把请求参数排序好以后,在末尾加上私钥,进行 MD5 加密。加密好的字符串作为 sign 和请求参数一起发给对方。
对方也按照这个规则进行加密,然后将加密以后的字符串和自己接收到的参数进行比对。
签名校验
CheckSum Structure
校验和计算参数:key1=val1&key2=val2&...&time={Unix时间戳}&UUID
请求API参数:key1=val1&key2=val2&...&time={Unix时间戳}&sign={签名值}
校验流程
客户端和服务器端都存储了一个私钥key。
客户端发送API请求前,会进行参数校验和计算,计算规则为:
1. 所有参数按照字母排序,排序后生成字符串str : k1=v1&k2&v2…;
2. 1中的str拼接私钥生成新的字符串{str&key};
3. 对2中的结果进行md5计算,生成sign值;
4. 对1中的str拼接sign校验和发送请求API;
5. 服务器对于请求参数去除sign字段进行重新计算,校验sign字段是否正确,并检查time字段是否在有效期内。
java示例代码
private Boolean checkSum(HttpServletRequest request) {
List<String> keys = new ArrayList<>();
keys.addAll(request.getParameterMap().keySet());
Collections.sort(keys);
StringBuilder sb = new StringBuilder();
String signValue = null;
for (String key : keys) {
String value = request.getParameter(key);
if (key.equals("sign")) {
signValue = value;
continue;
}
sb.append(key).append("=").append(value).append("&");
}
sb.append(config.key);
String md5Value = DigestUtils.md5Hex(sb.toString());
if (signValue != null && signValue.equals(md5Value)) {
return true;
}
return false;
}
MD5签名
在 MD5 签名时,需要私钥参与签名。 MD5 的私钥是以英文字母和数字组成的32位字符串。商户可登录到商户服务中心(https://b.alipay.com),安装数字证书,在“技术服务”栏目中点击“交易安全校验码”,即可查看。
请求时签名
当拿到请求时的待签名字符串后,需要把私钥直接拼接到待签名字符串后面,形成新的字符串,利用MD5的签名函数对这个新的字符串进行签名运算,从而得到32位签名结果字符串(该字符串赋值于参数sign)。
通知返回时验证签名
当获得到通知返回时的待签名字符串后,同理,需要把私钥直接拼接到待签名字符串后面,形成新的字符串,利用MD5的签名函数对这个新的字符串进行签名运算,从而得到32位签名结果字符串。此时这个新的字符串需要与支付宝通知返回参数中的参数sign的值进行验证是否相等,来判断签名是否验证通过。
参考资料:
下面的网络资料也来自于支付宝公司的即时到帐接口文档,可以直接参看文档。
http://www.oschina.net/question/163899_24007