## **数据签名**
为了保证数据传输过程中的数据真实性和完整性,我们需要对数据进行数字签名,在接收签名数据之后进 行签名校验。
数字签名有两个步骤,先按一定规则拼接要签名的原始串,再选择具体的算法和密钥计算出签名结果。 一般失败的结果不签名。
* * * * *
### 签名原始串
无论是请求还是应答,签名原始串按以下方式组装成字符串:
1、data 字段内,所有参数按照字段名的 ascii 码从小到大排序后使用 QueryString 的格式(即 key1=value1&key2=value2...)拼接而成,空值不传递,不参与签名组串。
2、签名原始串中,字段名和字段值都采用原始值,不进行 URL Encode。
3、返回的应答或通知消息可能会由于升级增加参数,请验证应答签名时注意允许这种情况。
* * * * *
### 签名算法
目前暂只支持 MD5 签名
MD5 签名
MD5 是一种摘要生成算法,通过在签名原始串后加上平台通信密钥的内容,进行 MD5 运算,形成的摘要字
符串即为签名结果。为了方便比较,签名结果统一转换为大写字符。
注意:签名时将字符串转化成字节流时指定的编码字符集应与参数 charset 一致。
MD5 签名计算公式:
sign = Md5(data数据原字符串&key=平台密钥). toUpperCase
toUpperCase 即MD5大写
PHP写法: strtoupper(Md5(data数据原字符串&key=平台密钥));
如:
假设以下为传入参数:
~~~
array(4) {
["appid"] => string(10) "1308791035"
["method"] => string(7) "wx_scan"
["data"] => array(3) {
["total"] => int(100)
["store_id"] => string(2) "11"
["nonce_str"] => string(13) "5ad1d0db143a2"
}
["sign"] => string(32) "1802BF462E9DCD422BCF42D181068655"
}
~~~
>[danger] **签名字段只针对Data字段数据**
如上data参数为
~~~
array(3) {
["total"] => int(100)
["store_id"] => string(2) "11"
["nonce_str"] => string(13) "5ad1d0db143a2"
}
~~~
假设平台通信密钥为:FFXHIXPOM6KV7OKOOEKV9L
1: 经过 a 过程 URL 键值对字典序排序后的字符串 string1 为:
~~~
nonce_str=5ad1d0db143a2&store_id=11&total=100
~~~
2: 经过 b 过程后得到 sign 为:
~~~
格式转变为:
sign=strtoupper(md5(string1&key=FFXHIXPOM6KV7OKOOEKV9L))
格式转变为:
sign=strtoupper(md5(nonce_str=5ad1d0db143a2&store_id=11&total=100&key=FFXHIXPOM6KV7OKOOEKV9L))
格式转变为:
sign=1802BF462E9DCD422BCF42D181068655
~~~
最终签名即为:
> 1802BF462E9DCD422BCF42D181068655