You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

phpseclib 2 RSA解密正常但phpseclib 3 RSA解密异常如何解决

问题复现代码

  • phpseclib 2 示例代码 - 运行正常
use phpseclib\Crypt\RSA;
$rsa = new RSA();
$rsa->loadKey($PRIVATE_KEY);
$key = $rsa->decrypt(base64_decode($a));
  • phpseclib 3 示例代码 - 运行异常
use phpseclib3\Crypt\PublicKeyLoader;

$private = PublicKeyLoader::load($PRIVATE_KEY);
$key = $private->decrypt(base64_decode($a));

两段代码逻辑均为加载RSA私钥后,对base64解码后的密文做解密操作,逻辑完全一致但运行结果不同。


版本不兼容的核心原因

phpseclib 3对RSA加解密的默认规则做了破坏性变更,和v2的默认行为不兼容:

  1. 填充模式默认值不同:v2解密时会自动遍历所有支持的填充模式(包括PKCS#1 v1.5、各哈希算法的OAEP填充)做匹配尝试,不需要手动指定;v3默认仅使用SHA256哈希的OAEP填充,不会自动降级尝试其他填充,密文填充和默认值不匹配时会直接解密失败。
  2. 校验严格度不同:v2对格式不规范的密钥、密文会自动做容错修正,v3默认开启严格格式校验,不符合ASN.1规范的输入会直接返回解密失败。

绝大多数跨版本解密失败的场景,都是因为旧业务生成的RSA密文采用了PKCS#1 v1.5填充(旧系统最常用的RSA加密填充标准),和v3默认的OAEP填充不匹配导致的。


修复方案

在v3中解密前显式指定和v2一致的填充模式即可,和旧逻辑对齐的代码如下:

use phpseclib3\Crypt\PublicKeyLoader;
use phpseclib3\Crypt\RSA;

// 加载私钥,若密钥格式不规范可将第二个参数设为false关闭严格校验
$private = PublicKeyLoader::load($PRIVATE_KEY);
// 显式指定填充模式为PKCS#1 v1.5,和v2默认行为对齐
$private = $private->withPadding(RSA::ENCRYPTION_PKCS1);
$key = $private->decrypt(base64_decode($a));

如果确认密文是OAEP填充但解密失败,可根据加密端使用的哈希算法替换对应填充常量:

  • 加密端用SHA1哈希的OAEP:RSA::ENCRYPTION_OAEP_WITH_SHA1
  • 加密端用MD5哈希的OAEP:RSA::ENCRYPTION_OAEP_WITH_MD5
  • 加密端用SHA512哈希的OAEP:RSA::ENCRYPTION_OAEP_WITH_SHA512

内容的提问来源于stack exchange,提问作者Jayendra Matarage

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 15:24:34