微信支付公钥使用介绍
更新时间:2024.05.08# 什么是微信支付公钥
以下两个场景需要使用微信支付公钥:商户在验证微信支付API应答和回调通知的签名时、商户加密 API 请求中的敏感信息。微信支付拥有“微信支付私钥”,商户拥有“微信支付公钥”,微信支付用私钥签名,商户使用公钥验签。请区别于“商户APIv2密钥”、“APIv3密钥”。
# 为什么使用微信支付公钥
金融类互联网应用的消息真实性和完整性至关重要。商户系统在收到微信支付的应答或回调通知时,需要验证消息的真实性(确保来自微信支付)和完整性(未被第三方篡改)。 微信支付对 HTTP 关键信息提供数字签名。商户通过使用微信支付公钥验证签名,可以确认收到的消息确实来自微信支付,而非其他恶意方伪造。这样,商户可以安心处理交易请求,避免因信任错误来源而导致的潜在风险。
# 获取微信支付公钥
需要超级管理员或者安全联系人登录商户平台,进入账户中心-API安全页面,点击申请公钥后,可下载微信支付公钥,请务必仔细查看指引完成开发
详情步骤介绍:
如果你是商户,请登录商户平台 (opens new window)(需要超级管理员或者安全联系人登录,安全联系人可由超管在安全中心-安全联系人设置),进入账户中心-API安全,找到“微信支付公钥”,点击申请公钥
如果你是服务商,请登陆合作伙伴平台 (opens new window)(需要超级管理员或者安全联系人登录,安全联系人可由超管在安全中心-安全联系人设置),进入账户中心-API安全,找到“微信支付公钥”,点击申请公钥
(1)帐户中心->API安全 | (2)微信支付公钥入口页面 |
---|---|
(3)下载微信支付公钥 | (4)得到公钥文件和公钥ID(公钥序列号) |
---|---|
# 使用微信支付公钥
# 使用微信支付公钥验签
# 获取签名及构造验签源串
商户开发者应仔细阅读 构造验签源串,了解如何获取应答和回调通知中的微信支付签名、如何构造验签源串。
# 验证签名
很多编程语言的签名验证函数支持对验签名串和签名进行签名验证。强烈建议商户调用该类函数,使用微信支付公钥对验签名串和签名进行 SHA256 with RSA 签名验证。
下面展示使用命令行演示如何进行验签。假设我们已经获取了微信支付公钥并保存为 1900009191_wxp_pub.pem
。内容如下:
1$ cat 1900009191_wxp_pub.pem2-----BEGIN PUBLIC KEY-----3MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4zej1cqugGQtVSY2Ah8RMCKcr2UpZ8Npo+5Ja9xpFPYkWHaF1Gjrn3d5kcwAFuHHcfdc3yxDYx6+9grvJnCA2zQzWjzVRa3BJ5LTMj6yqvhEmtvjO9D1xbFTA2m3kyjxlaIar/RYHZSslT4VmjIatW9KJCDKkwpM6x/RIWL8wwfFwgz2q3Zcrff1y72nB8p8P12ndH7GSLoY6d2Tv0OB2+We2Kyy2+QzfGXOmLp7UK/pFQjJjzhSf9jxaWJXYKIBxpGlddbRZj9PqvFPTiep8rvfKGNZF9Q6QaMYTpTp/uKQ3YvpDlyeQlYe4rRFauH3mOE6j56QlYQWivknDX9VrwIDAQAB4-----END PUBLIC KEY-----
然后,使用 base64 解码应答签名,将保存为文件signature.txt
。
1$openssl base64 -d -A <<< \ 'CtcbzwtQjN8rnOXItEBJ5aQFSnIXESeV28Pr2YEmf9wsDQ8Nx25ytW6FXBCAFdrr0mgqngX3AD9gNzjnNHzSGTPBSsaEkIfhPF4b8YRRTpny88tNLyprXA0GU5ID3DkZHpjFkX1hAp/D0fva2GKjGRLtvYbtUk/OLYqFuzbjt3yOBzJSKQqJsvbXILffgAmX4pKql+Ln+6UPvSCeKwznvtPaEx+9nMBmKu7Wpbqm/+2ksc0XwjD+xlvlECkCxfD/OJ4gN3IurE0fpjxIkvHDiinQmk51BI7zQD8k1znU7r/spPqB+vZjc5ep6DC5wZUpFu5vJ8MoNKjCu8wnzyCFdA==' > signature.txt
最后,验证签名,得到验签结果。
1$ openssl dgst -sha256 -verify 1900009191_wxp_pub.pem -signature signature.txt << EOF215542099803c5ac7061fccab6bf3e254dcf98995b8c4{"data":[{"serial_no":"5157F09EFDC096DE15EBE81A47057A7232F1B8E1","effective_time":"2018-03-26T11:39:50+08:00","expire_time":"2023-03-25T11:39:50+08:00","encrypt_certificate":{"algorithm":"AEAD_AES_256_GCM","nonce":"d215b0511e9c","associated_data":"certificate","ciphertext":"..."}}]}5EOF6Verified OK
如果你有关于签名探测任何疑问,请通过在线技术咨询 (opens new window)联系我们的技术支持。
# 使用微信支付公钥加密敏感信息
为了保证通信过程中敏感信息字段(如用户的住址、银行卡号、手机号码等)的机密性,微信支付API v3要求商户对上送的敏感信息字段进行加密。与之相对应,微信支付会对下行的敏感信息字段进行加密,商户需解密后方能得到原文。下面详细介绍加解密的方式,以及如何进行相应的计算。
我们提供了微信支付API v3官方SDK(目前包含Java (opens new window)、PHP (opens new window)、 Go (opens new window)三种语言版本),使用官方 SDK 调用微信支付接口,无需关心签名生成和验证,接入更方便。
# 1. 加密算法
敏感信息加密使用的RSA公钥加密算法 (opens new window)。加密算法使用的填充方案,我们使用了相对更安全的RSAES-OAEP(Optimal Asymmetric Encryption Padding)。
RSAES-OAEP在各个编程语言中的模式值为:
- OpenSSL (opens new window),padding设置为
RSA_PKCS1_OAEP_PADDING
- Java,使用
Cipher.getinstance(RSA/ECB/OAEPWithSHA-1AndMGF1Padding)
- PHP (opens new window),padding设置为
OPENSSL_PKCS1_OAEP_PADDING
- .NET (opens new window),fOAEP设置为true
- Node.js (opens new window),padding设置为
crypto.constants.RSA_PKCS1_OAEP_PADDING
- GO (opens new window),使用
EncryptOAEP
开发者应当使用微信支付公钥,对上送的敏感信息进行加密。这样只有拥有私钥的微信支付才能对密文进行解密,从而保证了信息的机密性。
另一方面,微信支付使用 商户证书中的公钥对下行的敏感信息进行加密。开发者应使用商户私钥对下行的敏感信息的密文进行解密。
# 2. 加密示例
开发者应当使用微信支付公钥,对上送的敏感信息进行加密。
大部分编程语言支持RSA公钥加密。你可以参考示例,了解如何使用您的编程语言实现敏感信息加密。