RSA公钥错误error:04099079问题排查与修复请求
修复PHP RSA加密中的公钥错误与OAEP解码问题
问题根源分析
- 硬编码公钥忽略传入参数:
encryptMessage函数内部硬编码了固定公钥,完全没有使用传入的$receiverPublicKey参数,导致始终用同一个错误格式的公钥尝试加密。 - PEM公钥格式错误:硬编码的公钥没有按标准PEM格式换行——公钥内容需要在
-----BEGIN PUBLIC KEY-----后开始,每64个字符换行一次,最后-----END PUBLIC KEY-----单独占一行。 - 错误提示的OAEP关联:虽然当前代码用的是
OPENSSL_PKCS1_PADDING,但之前注释的OAEP代码可能残留了错误日志,核心问题还是公钥的有效性。
修复后的代码实现
crypto_library.php 中的 encryptMessage 函数
/** * @param string $message 待加密的明文消息 * @param string $publicKey 接收方的PEM格式公钥 * @return string Base64编码的加密结果 * @throws Exception 公钥无效或加密失败时抛出异常 */ function encryptMessage($message, $publicKey) { // 自动格式化公钥为标准PEM格式(补充必要换行) $formattedPublicKey = preg_replace( '/-----BEGIN PUBLIC KEY-----(.*?)-----END PUBLIC KEY-----/s', "-----BEGIN PUBLIC KEY-----\n" . wordwrap($1, 64, "\n", true) . "\n-----END PUBLIC KEY-----", $publicKey ); // 加载公钥资源 $publicKeyResource = openssl_pkey_get_public($formattedPublicKey); if (!$publicKeyResource) { throw new Exception('Incorrect public key: ' . openssl_error_string()); } // 使用更安全的OAEP填充方式加密 if (!openssl_public_encrypt($message, $encrypted, $publicKeyResource, OPENSSL_PKCS1_OAEP_PADDING)) { openssl_free_key($publicKeyResource); throw new Exception('Encryption failed: ' . openssl_error_string()); } openssl_free_key($publicKeyResource); return base64_encode($encrypted); }
关键修复点说明
- 使用传入的公钥参数:移除硬编码的固定公钥,改为使用函数参数
$publicKey,确保加密使用的是接收方的正确公钥。 - 自动修复公钥格式:通过正则和
wordwrap函数,自动为没有换行的公钥补充标准格式的换行,避免因格式问题导致openssl无法识别公钥。 - 改用安全的OAEP填充:替换原有的
OPENSSL_PKCS1_PADDING为更安全的OPENSSL_PKCS1_OAEP_PADDING,同时添加加密失败的异常捕获,便于排查问题。 - 完善注释与异常处理:补充函数注释,明确参数和异常情况,加密失败时及时释放公钥资源。
额外检查事项
- 确认
getPublicKey函数返回的公钥是完整的PEM格式(包含-----BEGIN PUBLIC KEY-----和-----END PUBLIC KEY-----标记)。 - 如果数据库中存储的公钥没有换行,上述代码会自动处理,但建议在存储公钥时就提前格式化好标准格式,减少运行时处理开销。
- 确保PHP环境已启用OpenSSL扩展,且版本支持OAEP填充(PHP 5.3.0及以上版本均支持)。
内容的提问来源于stack exchange,提问作者user22265143
相关产品推荐
相关产品推荐

