微信支付--签名篇
微信支付签名篇
前言
微信支付是一款基于微信客户端提供的支付服务功能,向商户提供销售经营分析、账户和资金管理的功能支持。用户通过扫描二维码、反扫二维码等多种方式调起微信支付模块完成支付。在这些支付流程中,签名是一个至关重要的步骤。下面我们将详细描述微信支付签名的内容。
原始签名字符串
无论是请求还是响应,都需要在HTTP头部或URL参数中包含一个名为`sign`的字段,这个字段就是原始签名字符串。原始签名字符串由以下几个部分组成:
* `nonce_str`:一个随机生成的32位字母数字串,用于防止重复请求。
* `timestamp`:当前时间戳,用于防止请求被缓存。
* `body`:支付相关信息,如订单金额、商品名称等。
* `key`:商户密钥,用于签名。
签名算法
微信支付使用HMAC-SHA256算法来生成签名。具体步骤如下:
1. 将`nonce_str`、`timestamp`和`body`三个部分用`&`连接起来,形成一个字符串。
2. 使用商户密钥`key`对这个字符串进行HMAC-SHA256加密。
3. 得到签名结果后,将其转换为小写。
签名校验
在微信支付的响应中,也会包含一个名为`sign`的字段,这个字段就是原始签名字符串。商户需要对这个签名进行校验,以确保请求是来自微信支付系统的。
1. 将响应中的`sign`字段取出。
2. 使用商户密钥`key`对响应中的`nonce_str`、`timestamp`和`body`三个部分用`&`连接起来,形成一个字符串。
3. 使用HMAC-SHA256算法对这个字符串进行加密。
4. 得到签名结果后,将其转换为小写。
5. 与响应中的`sign`字段比较,如果相同,则表示请求是来自微信支付系统的。
示例代码
以下是使用Python语言编写的示例代码,用于生成和校验签名:
```pythonimport hmacimport hashlibdef generate_sign(nonce_str, timestamp, body, key):
将nonce_str、timestamp和body三个部分用&连接起来 sign_string = f"{nonce_str}&{timestamp}&{body}"
使用商户密钥key对sign_string进行HMAC-SHA256加密 sign = hmac.new(key.encode(), sign_string.encode(), hashlib.sha256).hexdigest()
return signdef verify_sign(sign, nonce_str, timestamp, body, key):
将响应中的sign字段取出 received_sign = sign 使用商户密钥key对nonce_str、timestamp和body三个部分用&连接起来 expected_sign_string = f"{nonce_str}&{timestamp}&{body}"
使用HMAC-SHA256算法对expected_sign_string进行加密 expected_sign = hmac.new(key.encode(), expected_sign_string.encode(), hashlib.sha256).hexdigest()
将expected_sign转换为小写 expected_sign = expected_sign.lower()
与响应中的sign字段比较,如果相同,则表示请求是来自微信支付系统的 return received_sign == expected_sign生成签名nonce_str = "12345678"
timestamp = int(time.time())
body = {"amount":100, "goods_name": "测试商品"}
key = "your_merchant_key"
sign = generate_sign(nonce_str, timestamp, body, key)
print(sign)
校验签名received_sign = signis_valid = verify_sign(received_sign, nonce_str, timestamp, body, key)
print(is_valid)
```
结论
微信支付的签名是一个至关重要的步骤,用于防止请求被篡改和重复发送。通过使用HMAC-SHA256算法对原始签名字符串进行加密,可以生成一个安全的签名。商户需要对响应中的签名进行校验,以确保请求是来自微信支付系统的。在示例代码中,我们提供了一个用于生成和校验签名的Python函数,供商户参考使用。