使用OpenSSL做RSA签名验证 支付宝移动快捷支付 的服务器异步通知

本文档详细介绍了如何使用OpenSSL库在C++中进行RSA签名验证,以确认支付宝移动快捷支付的服务器异步通知的合法性。在支付宝的移动支付中,他们采用了RSA而非MD5进行签名,增加了开发复杂性。文中阐述了RSA签名和验证的步骤,以及具体使用openssl库的函数RSA_verify进行验证的方法,并提供了示例代码。
摘要由CSDN通过智能技术生成

由于业务需要,我们需要使用支付宝移动快捷支付做收款。支付宝给了我们《移动快捷支付应用集成接入包支付接口》见支付宝包《WS_SECURE_PAY_SDK》。

支付宝给的服务器demo只有Java、C#、PHP三种,而我们服务器端使用的是C++。这其中就涉及到接收支付宝的服务器异步通知。为了确保接收到的服务器异步通知来至支付宝,我们就必须验证支付宝的签名。坑爹的是,原来PC端使用MD5做签名,估计支付宝考虑到移动端的风险更高,于是改用RSA做移动快捷支付应用的签名。这无疑增加了我们迁移到移动端的开发成本。

支付宝文档中说明是使用openssl,我们这边就决定使用openssl做rsa签名验证。

由于第一次使用openssl做RSA验证签名,我们碰到了各种坑,为了避免其他项目也碰到类似问题,分享如下:


首先要说明的是RSA签名和签名验证的过程。

RSA签名的过程(支付宝操作)如下:对需要签名的字符串按key的字母升序排序,使用=和&连接,形成一个签名字符串。对该字符串做摘要(可以使用MD5或者SHA1,支付宝使用的是SHA1),然后对摘要字符串(即接口中的hash参数)使用支付宝私钥做RSA加密,获得加密字符串,即为签名字符串(放在sign中),设置sign_type=RSA。这样,就完成了发送字符串的签名。

RSA签名验证的过程(我们第三方企业操作)如下:接收到发送过来的字符串(如果字符串没有做url decode解码,需要做url decode解码),拆分为key、value对,按照支付宝的文档,根据key的字母升序排序,使用=和&链接,获得被签名字符串。被签名字符串做SHA1摘要算法,获得SHA1摘要字符串。如果sign_type=RSA,先将sign字段做base64解码,然后使用支付宝公钥做RSA解密,得到SHA1摘要字符串。比较两个SHA1摘要字符串,如果SHA1摘要字符串一致,则签名验证成功。

特别说明的是:支付宝的公钥字符串为以-----BEGIN PUBLIC KEY-----\n开始,以\n-----END PUBLIC KEY-----\n结束,中间的字符串需要每64个字符换行一次,即为:

-----BEGIN PUBLIC KEY----
RSA 加解密算法和 RSA 签名验证算法都是基于公钥加密的算法,需要使用 OpenSSL 库中提供的 RSA 函数来实现。以下是使用 OpenSSL 编写 RSA 加解密算法和 RSA 签名验证算法的步骤: 1. 生成 RSA 密钥对 使用 OpenSSLRSA_generate_key 函数可以生成 RSA 密钥对,示例代码如下: ```c RSA *rsa = RSA_new(); BIGNUM *e = BN_new(); int bits = 2048; unsigned long exponent = RSA_F4; BN_set_word(e, exponent); RSA_generate_key_ex(rsa, bits, e, NULL); ``` 2. RSA 加密 使用 OpenSSLRSA_public_encrypt 函数可以对数据进行 RSA 公钥加密,示例代码如下: ```c int len = RSA_public_encrypt(data_len, data, encrypted, rsa, RSA_PKCS1_PADDING); ``` 其中,data 是要加密的数据,data_len 是数据长度,encrypted 是加密后的数据缓冲区,rsaRSA 公钥。 3. RSA 解密 使用 OpenSSLRSA_private_decrypt 函数可以对数据进行 RSA 私钥解密,示例代码如下: ```c int len = RSA_private_decrypt(encrypted_len, encrypted, decrypted, rsa, RSA_PKCS1_PADDING); ``` 其中,encrypted 是加密后的数据,encrypted_len 是数据长度,decrypted 是解密后的数据缓冲区,rsaRSA 私钥。 4. RSA 签名 使用 OpenSSLRSA_sign 函数可以对数据进行 RSA 签名,示例代码如下: ```c unsigned int sig_len; unsigned char sig[256]; int ret = RSA_sign(NID_sha256, data, data_len, sig, &sig_len, rsa); ``` 其中,data 是要签名的数据,data_len 是数据长度,sig 是签名后的数据缓冲区,rsaRSA 私钥。 5. RSA 验证签名 使用 OpenSSLRSA_verify 函数可以对数据进行 RSA 验证签名,示例代码如下: ```c int ret = RSA_verify(NID_sha256, data, data_len, sig, sig_len, rsa); ``` 其中,data 是要验证签名的数据,data_len 是数据长度,sig 是签名数据,sig_len 是签名数据长度,rsaRSA 公钥。 需要注意的是,以上示例代码仅为参考,实际使用时需要根据具体情况进行修改和完善。
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值