Yii2中使用phpseclib3实现MD5+RSA签名对接API时服务端校验问题求助
Hi 👋,看你第一次尝试用MD5+RSA签名对接API,已经写出了本地验证通过的代码,这点超棒!不过看起来把签名发给服务端后遇到了校验不通过的问题?我结合你的代码帮你梳理几个常见的排查方向,看看能不能定位问题:
核对待签名原始字符串的一致性
服务端校验签名时,必须使用和你完全相同的原始字符串(就是你代码里的$string)。要重点检查:- 字符串里的每一个字符、空格、标点是否完全一致,比如你这里的时间戳
2024-04-30 15:30:41.446,服务端生成的时间格式是否和你完全匹配?有没有时区差异导致时间字符串不同? - 有没有在传递过程中被URL编码、转义或者截断?比如如果是POST表单提交,要确保字符串没有被自动转义。
- 字符串里的每一个字符、空格、标点是否完全一致,比如你这里的时间戳
检查签名的编码格式是否符合API要求
你现在用base64_encode处理签名,但有些API可能要求十六进制编码(用bin2hex($signature)),或者对Base64的格式有特殊要求(比如去掉换行、替换+//为-/_的URL安全Base64)。可以对照API文档里的示例签名格式,看看你的输出是否匹配。确认RSA的填充模式和哈希算法是否匹配
你代码里设置了->withPadding(RSA::SIGNATURE_PKCS1)->withHash('md5'),一定要确保API文档里要求的填充模式就是PKCS1,哈希算法确实是MD5。如果服务端用的是PSS填充或者SHA系列哈希,那肯定会校验失败。检查私钥的加载是否无问题
虽然你本地验证通过了,但还是要确认私钥文件的格式是否正确:- 私钥是不是标准的PEM格式?有没有多余的空行、注释或者格式错误?
- 可以尝试打印
$privateKey的信息(比如var_dump($privateKey)),确认加载后的RSA对象是正常的,没有加载错误。
验证服务端使用的公钥是否配对
你本地用私钥对应的公钥验证通过,但要确保服务端手里的公钥和你的私钥是配对的。可以导出你的公钥(用echo $privateKey->getPublicKey()->toString('PEM');),让服务端确认他们用的是不是这个公钥,或者你用这个公钥手动模拟服务端的校验流程,看看是否能通过。
附上你当前的代码(已修正语法转义问题):
use phpseclib3\Crypt\RSA; use phpseclib3\Crypt\PublicKeyLoader; $string = 'fl_testENQJKAZXT00JJA0012202024-04-30 15:30:41.446'; // Load the private key $privateKeyPath = Yii::getAlias('@webroot').'/bla.key'; //1024-bit $privateKeyContents = file_get_contents($privateKeyPath); // Load the private key into the RSA object $privateKey = PublicKeyLoader::load($privateKeyContents); // Set the signature mode $privateKey = $privateKey->withPadding(RSA::SIGNATURE_PKCS1)->withHash('md5'); $signature = $privateKey->sign($string); $signature = base64_encode($signature); echo $privateKey->getPublicKey()->verify($string, $signature) ? 'valid signature' : 'invalid signature'; die;
备注:内容来源于stack exchange,提问作者Shaho

