PHP使用RSA私钥解密报错padding check failed如何解决
你遇到的error:04065072:rsa routines:rsa_ossl_private_decrypt:padding check failed报错核心原因是RSA解密阶段填充校验失败,大概率是两端填充模式不匹配、密文预处理逻辑不一致导致的,可按以下步骤排查修复:
对齐两端填充模式
PHP的openssl_private_decrypt函数默认使用OPENSSL_PKCS1_PADDING(PKCS#1 v1.5填充),如果C#加密端使用的是其他填充方案,需要手动指定PHP端的填充参数:- 若C#用OAEP填充:第四个参数传
OPENSSL_PKCS1_OAEP_PADDING - 若C#用无填充:第四个参数传
OPENSSL_NO_PADDING(注意无填充需要自行处理解密后的前导零冗余数据)
先确认C#加密代码的填充配置,和PHP端保持一致即可解决大部分此类报错。
- 若C#用OAEP填充:第四个参数传
校验密文预处理逻辑
确认C#加密后的输出是否做了额外转义处理:
部分C#实现会输出URL安全的Base64(将+替换为-、/替换为_、删除末尾补位的=),你需要在PHP解码前先还原为标准Base64格式,示例代码:$data = str_replace(['-','_'], ['+','/'], $data); $data = base64_decode(str_pad($data, strlen($data) % 4, '=', STR_PAD_RIGHT));同时确认密文传输过程中没有丢失、追加多余字符。
校验私钥加载有效性
你现有代码用@屏蔽了文件读取错误,先移除错误抑制符,确认私钥文件路径正确、读取成功,同时增加私钥解析有效性校验,避免无效私钥导致解密异常。
修正后的参考代码
class RSA{ protected $private; // 可根据C#端配置调整填充参数 protected $padding = OPENSSL_PKCS1_PADDING; public function __construct() { $this->private = file_get_contents("private.pem"); if (!$this->private) { throw new RuntimeException('私钥文件读取失败'); } } public function decrypt($data) { if (empty($data) || !is_string($data)) { throw new RuntimeException('待解密数据非法'); } if (empty($this->private)) { throw new RuntimeException('私钥未配置'); } // 解析私钥 $key = openssl_get_privatekey($this->private); if (!$key) { throw new Exception('私钥解析失败:' . openssl_error_string()); } // 处理URL安全Base64,不需要可删除这两行 $data = str_replace(['-','_'], ['+','/'], $data); $decodeData = base64_decode(str_pad($data, strlen($data) % 4, '=', STR_PAD_RIGHT)); // 解密 if (!openssl_private_decrypt($decodeData, $result, $key, $this->padding)){ throw new Exception('解密失败:' . openssl_error_string()); } return $result; } }
内容的提问来源于stack exchange,提问作者OS Coder
相关产品推荐
相关产品推荐

