PHP与JavaScript RSA加解密失败求助:OAEP解码错误
问题根源及解决方法
1. 参数传递错误
PHP解密逻辑中错误地使用了$_POST["username"]作为密文参数,但前端实际传递的密文参数是encrypted_data,这直接导致解密时使用了错误的数据,必然失败。
修正代码:
$data = decryptData( ciphertext: $_POST["encrypted_data"], // 替换原有的$_POST["username"] key_id: $_POST["key_id"] );
2. RSA-OAEP哈希算法不匹配
JavaScript端导入公钥时明确指定了SHA-256作为哈希算法:
return window.crypto.subtle.importKey( 'spki', binary_key, { name: 'RSA-OAEP', hash: 'SHA-256' // 前端指定SHA-256哈希 }, true, ["encrypt"] );
但PHP默认的OPENSSL_PKCS1_OAEP_PADDING填充模式使用的是SHA-1哈希算法,两边哈希算法不一致会触发OAEP解码错误,也就是你遇到的error:04099079:rsa routines:RSA_padding_check_PKCS1_OAEP_mgf1:oaep decoding error。
修正代码(PHP解密函数):
使用openssl_decrypt并指定RSA-OAEP算法及SHA-256哈希,确保和前端加密逻辑一致:
function decryptData($ciphertext, $key_id){ global $database; $b64_ciphertext = base64_decode($ciphertext); $private_key_string = $database->get_encryption_key($key_id); $private_key = openssl_pkey_get_private($private_key_string); $decrypted_data = openssl_decrypt( $b64_ciphertext, 'RSA-OAEP', $private_key, OPENSSL_RAW_DATA, '', // 无附加数据,留空 'sha256' // 匹配前端的SHA-256哈希 ); if ($decrypted_data === false) { $error = openssl_error_string(); die(json_encode(["OpenSSL错误: " . $error])); } openssl_pkey_free($private_key); return $decrypted_data; }
额外验证建议
- 确保数据库中存储的私钥是完整的PEM格式,没有被截断或修改
- 测试时可直接使用你提供的测试密文、公钥和私钥,验证修正后的代码是否能正确解密
内容的提问来源于stack exchange,提问作者BenjeminStar
相关产品推荐
相关产品推荐

