
phpseclib 3 默认使用 SHA256 作为 OAEP 的哈希与 MGF1 哈希算法,而 phpseclib 2 默认使用 SHA1,导致相同密钥和密文在 v3 中解密失败;需显式指定 withHash("sha1")->withMGFHash("sha1") 以保持兼容。
phpseclib 3 默认使用 sha256 作为 oaep 的哈希与 mgf1 哈希算法,而 phpseclib 2 默认使用 sha1,导致相同密钥和密文在 v3 中解密失败;需显式指定 `withhash("sha1")->withmgfhash("sha1")` 以保持兼容。
在从 phpseclib 2 升级到 phpseclib 3 的过程中,RSA 解密突然失败是一个常见但易被忽视的问题。根本原因在于:两个版本虽均默认采用 OAEP 填充方案,但底层哈希算法不一致。
- ✅ phpseclib 2:OAEP 中的主哈希(hash)与掩码生成函数哈希(MGF1 hash)默认均为
SHA1 - ✅ phpseclib 3:为提升安全性,默认统一升级为
SHA256
由于 OAEP 解密严格校验哈希参数,若加密时使用的是 v2(即 SHA1-OAEP),而解密时 v3 按默认尝试 SHA256-OAEP,则会返回 false 或抛出异常(如 Decryption error),即使私钥正确、密文无误。
✅ 正确的 phpseclib 3 解密写法(兼容 v2 加密)
use phpseclib3\Crypt\PublicKeyLoader;
$private = PublicKeyLoader::load($PRIVATE_KEY);
$decrypted = $private
->withHash('sha1') // 显式指定 OAEP 主哈希
->withMGFHash('sha1') // 显式指定 MGF1 哈希
->decrypt(base64_decode($a));
if ($decrypted === false) {
throw new RuntimeException('RSA decryption failed — check key format, padding, or hash compatibility.');
}⚠️ 注意事项:
withHash()和withMGFHash()必须同时设置,且值一致(均为'sha1'),否则仍会失败;- 私钥格式需兼容 v3(推荐 PEM 格式,含
-----BEGIN PRIVATE KEY-----或-----BEGIN RSA PRIVATE KEY-----头尾);- 若你控制加密端,强烈建议统一迁移到 SHA256:v2 可通过
$rsa->setHash('sha256')和$rsa->setMGFHash('sha256')配置,v3 则无需额外设置——这是更安全、更面向未来的做法。
? 安全说明
尽管 SHA1 在签名与证书场景中已被弃用,但在 OAEP 构造中,目前尚无已知实际攻击能利用 SHA1 的碰撞弱点实现解密绕过(参见 Security StackExchange 分析)。不过,遵循密码学演进原则,新项目应优先选用 SHA256 或更高强度哈希(如 SHA512),并确保加解密两端算法严格对齐。
立即学习“PHP免费学习笔记(深入)”;
简言之:兼容旧数据用 ->withHash('sha1')->withMGFHash('sha1');构建新系统,请默认信赖 v3 的 SHA256,并在加密侧同步升级——这才是健壮、可持续的 RSA 实践路径。



















