安全规范
数字签名
为了保证数据传输过程中的数据真实性和完整性,我们需要对数据进行数字签名,在接收签名数据之后进行签名校验。
数字签名有两个步骤,先按一定规则拼接要签名的原始串,再选择具体的算法和密钥计算出签名结果。
一般失败的结果不签名。
签名原始串
无论是请求还是应答,签名原始串按以下方式组装成字符串:
1、除sign字段外,所有参数按照字段名的ascii码从小到大排序后使用QueryString的格式(即key1=value1&key2=value2…)拼接而成,空值 不传递,不参与签名组串。
2、签名原始串中,字段名和字段值都采用原始值,不进行URL Encode。
3、平台返回的应答或通知消息可能会由于升级增加参数,请验证应答签名时注意允许这种情况。
举例:
调用某个接口,接口有如下字段:
<xml>
<body><![CDATA[测试支付]]></body>
<mch_create_ip><![CDATA[127.0.0.1]]></mch_create_ip>
<mch_id><![CDATA[755437000006]]></mch_id>
<nonce_str><![CDATA[1409196838]]></nonce_str>
<notify_url><![CDATA[http://227.0.0.1:9001/javak/]]></notify_url>
<out_trade_no><![CDATA[141903606228]]></out_trade_no>
<service><![CDATA[unified.trade.pay]]></service>
<sign><![CDATA[6DD83E271779D6D885748A2C2A4D9CFD]]></sign>
<total_fee><![CDATA[1]]></total_fee>
</xml>
正确的签名字段排序为:
body=测试支付&mch_create_ip=127.0.0.1&mch_id=755437000006&nonce_str=1409196838¬ify_url=CDATA[http://227.0.0.1:9001/javak/&out_trade_no=
141903606228&service=unified.trade.pay&total_fee=1
签名算法
目前暂只支持MD5签名
MD5签名
MD5 是一种摘要生成算法,通过在签名原始串后加上商户通信密钥的内容,进行MD5运算,形成的摘要字符串即为签名结果。为了方便比较,签名结果统一转换为大写字符。
注意:签名时将字符串转化成字节流时指定的编码字符集应与参数charset一致。
MD5签名计算公式:
sign = Md5(原字符串&key=商户密钥).toUpperCase
如:
假设以下为 XML 传入参数:
<xml>
<body><![CDATA[测试支付]]></body>
<mch_create_ip><![CDATA[127.0.0.1]]></mch_create_ip>
<mch_id><![CDATA[755437000006]]></mch_id>
<nonce_str><![CDATA[1409196838]]></nonce_str>
<notify_url><![CDATA[http://227.0.0.1:9001/javak/]]></notify_url>
<out_trade_no><![CDATA[141903606228]]></out_trade_no>
<service><![CDATA[unified.trade.pay]]></service>
<sign><![CDATA[6DD83E271779D6D885748A2C2A4D9CFD]]></sign>
<total_fee><![CDATA[1]]></total_fee>
</xml>
假设商户密钥为:7daa4babae15ae17eee90c9e
i:经过 a 过程 URL 键值对字典序排序后的字符串 string1 为:
body=测试支付&mch_create_ip=127.0.0.1&mch_id=755437000006&nonce_str=1409196838¬ify_url=http://227.0.0.1:9001/javak/&out_trade_no=
141903606228&service=unified.trade.pay&total_fee=1
ii:经过 b 过程后得到 sign 为:
sign
=md5(string1&key=7daa4babae15ae17eee90c9e).toUpperCase
=md5(body=测试支付&mch_create_ip=127.0.0.1&mch_id=755437000006&nonce_str=1409196838¬ify_url=http://227.0.0.1:9001/javak/&out_trade_no=
141903606228&service=unified.trade.pay&total_fee=1&key=
7daa4babae15ae17eee90c9e).toUpperCase()
=”6DD83E271779D6D885748A2C2A4D9CFD”