Open TheNorthMemory opened 1 month ago
- OS:MacOS - PHP: 8.3.7 - wechatpay-php: 1.4.9
这可能不应该是件公开讨论的事宜,有关应用安全的问题可能需要具有专业知识的人来共同探讨,然而此问题在开源社区有了许多公开讨论,暂且先把问题及可能的解决方案记录于此。
在例行性更新本地PHP版本的时候,按操作习惯,会run一遍测试用例,然而有许久如下测试用例有一条F一直悬而未决:
run
https://github.com/wechatpay-apiv3/wechatpay-php/blob/2cabc8a15136050c4ee61083cd24959114756a03/tests/Crypto/RsaTest.php#L307-L321
翻阅了PHP的更新历史及OpenSSL的更新历史,发现如下两条重要更新:
PHP自8.1.0起,使用了OpenSSL的EVP_PKEY API,且OpenSSL自3.2.0起,已显式调整EVP_PKEY_decrypt处理逻辑,默认当填充方式为RSA_PKCS1_PADDING解密失败时,不再抛异常,代为输出为随机字符串。这即是 "encrypted as OPENSSL_PKCS1_OAEP_PADDING, and decrpted as OPENSSL_PKCS1_PADDING" 用例测试未通过的原因所在。
EVP_PKEY API
EVP_PKEY_decrypt
RSA_PKCS1_PADDING
公开的CVE/patch/backport如:
都提到了一点是,RSAES-PKCS1-v1_5已不再安全并且容易受到攻击。
RSAES-PKCS1-v1_5
目前已知在微信支付海外版,有如下两个接口声明的非对称加密方案为RSAES-PKCS1-v1_5:
身份信息校验API
• 使用微信支付平台证书的公钥,对于需要加密的参数值进行 RSA 加密。填充方案使用 RSAES-PKCS1-v1_5。
Onboard Sub-merchant API
1、Perform the RSA encryption for the parameter values with the public key of the WeChat Pay Platform certificate. Use RSAES-PKCS1-v1_5 as the filling scheme.
建议微信支付团队,评估影响等级及寻求解决方案。
本SDK(wechatpay-php)自1.2.1起,提供了OPENSSL_PKCS1_PADDING加解密支持,目前客户端暂时未发现使用OPENSSL_PKCS1_PADDING解密的场景,出于兼容性及安全考虑,需要:
OPENSSL_PKCS1_PADDING
\WeChatPay\Crypto\Rsa::decrpt
OpenSSL>3.2.0
WeChatPay\Tests\Crypto\RsaTest::testCrossEncryptDecryptWithDifferentPadding
运行环境
描述你的问题现象
这可能不应该是件公开讨论的事宜,有关应用安全的问题可能需要具有专业知识的人来共同探讨,然而此问题在开源社区有了许多公开讨论,暂且先把问题及可能的解决方案记录于此。
缘由
在例行性更新本地PHP版本的时候,按操作习惯,会
run
一遍测试用例,然而有许久如下测试用例有一条F一直悬而未决:https://github.com/wechatpay-apiv3/wechatpay-php/blob/2cabc8a15136050c4ee61083cd24959114756a03/tests/Crypto/RsaTest.php#L307-L321
现状
翻阅了PHP的更新历史及OpenSSL的更新历史,发现如下两条重要更新:
PHP自8.1.0起,使用了OpenSSL的
EVP_PKEY API
,且OpenSSL自3.2.0起,已显式调整EVP_PKEY_decrypt
处理逻辑,默认当填充方式为RSA_PKCS1_PADDING
解密失败时,不再抛异常,代为输出为随机字符串。这即是 "encrypted as OPENSSL_PKCS1_OAEP_PADDING, and decrpted as OPENSSL_PKCS1_PADDING" 用例测试未通过的原因所在。公开的CVE/patch/backport如:
都提到了一点是,
RSAES-PKCS1-v1_5
已不再安全并且容易受到攻击。受影响
目前已知在微信支付海外版,有如下两个接口声明的非对称加密方案为
RSAES-PKCS1-v1_5
:身份信息校验API
Onboard Sub-merchant API
解决方案
服务端
建议微信支付团队,评估影响等级及寻求解决方案。
客户端
本SDK(wechatpay-php)自1.2.1起,提供了
OPENSSL_PKCS1_PADDING
加解密支持,目前客户端暂时未发现使用OPENSSL_PKCS1_PADDING
解密的场景,出于兼容性及安全考虑,需要:\WeChatPay\Crypto\Rsa::decrpt
函数,当使用OPENSSL_PKCS1_PADDING
填充方案时,给予废弃及安全提示,不再推荐使用;OpenSSL>3.2.0
默认行为保持一致,代为输出为随机字符串;WeChatPay\Tests\Crypto\RsaTest::testCrossEncryptDecryptWithDifferentPadding
用例覆盖;