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

PHP8.1(OpenSSL3.0)无法解密PHP8.0(OpenSSL1.1)加密的PKCS7数据求助

OpenSSL 3.0下无法解密旧版本OpenSSL加密的PKCS7数据问题

原服务器环境为Alpine Linux 3.15 + PHP 8.0(依赖OpenSSL 1.1.x),使用openssl_pkcs7_encrypt()加密数据并存入数据库后,可通过openssl_pkcs7_decrypt()正常解密。

升级到Alpine Linux 3.17 + PHP 8.1(依赖OpenSSL 3.0)后,使用openssl_pkcs7_decrypt()解密此前加密的数据失败,通过openssl_error_string()获取到的错误信息如下:

  • error:10800077:PKCS7 routines::decrypt error
  • error:0308010C:digital envelope routines::unsupported
  • 后续8条重复错误:error:12000079:random number generator::Cannot open file

已尝试以下操作但未解决问题:

  • 安装openssl1.1兼容包:apk add openssl1.1-compat
  • 注释/etc/ssl/openssl.cnf中的RANDFILE = $ENV::HOME/.rnd配置项

求问是否有类似问题的解决经验,或可行的修复建议?

加密解密示例代码

<?php

function GetOpenSSLErrors()
{
    $openSSLErrors = "";
    $errorCounter = 0;
    while ( ($currentError = openssl_error_string()) !== false) 
    {
        ++$errorCounter;
        $openSSLErrors = $openSSLErrors . "$errorCounter. - $currentError ";
    }

    return $openSSLErrors;
}

function Decrypt($encryptedMessage, $privateKey, $certificate, &$error = "")
{
    $decrypted              = NULL;
    $fileEncryptedMessage   = "EncryptedMessage.txt";
    $fileDecryptedMessage   = "DecryptedMessage.txt";

    if(file_put_contents($fileEncryptedMessage, $encryptedMessage) === false) {
        $error = "Failed to write received message for RSA decryption to the file '$fileEncryptedMessage'";
    }
    else if(openssl_pkcs7_decrypt($fileEncryptedMessage, $fileDecryptedMessage, $certificate, $privateKey)) {
        $decrypted = file_get_contents($fileDecryptedMessage,true);
        if (!$decrypted) {
            $error = "Failed to get content decrypted by openssl_pkcs7_decrypt from file [$fileDecryptedMessage]";
        }
    } else {
        $error = "Failed to openssl_pkcs7_decrypt content of file [$fileEncryptedMessage], openSSL errors [" . GetOpenSSLErrors() . "]";
    }

    // Delete any created files
    if (file_exists ($fileEncryptedMessage)) unlink($fileEncryptedMessage);
    if (file_exists ($fileDecryptedMessage)) unlink($fileDecryptedMessage);

    return $decrypted;
}

function Encrypt($messageToEncrypt, $certificate, &$error = "")
{
    $returnValue = NULL;
    $fileMessageToEncrypt = "MessageToEncrypt.txt";
    $fileEncryptedMessage = "EncryptedMessage.txt";

    if(file_put_contents($fileMessageToEncrypt, $messageToEncrypt) === false) {
        $error = "Failed to write received message for RSA encryption to the file '$fileEncryptedMessage'";
    }
    else if (openssl_pkcs7_encrypt($fileMessageToEncrypt, $fileEncryptedMessage, $certificate, NULL)) {
        $returnValue = file_get_contents($fileEncryptedMessage,true);

        if (!$returnValue) {
            $returnValue = NULL;
            $error = "Failed to get content encrypted by openssl_pkcs7_encrypt from file [$fileEncryptedMessage]";
        }
    } else {
        $error = "Failed to openssl_pkcs7_encrypt content of file [$fileMessageToEncrypt], openSSL errors [" . GetOpenSSLErrors() . "]";
    }
    
    // Delete any created files
    if (file_exists ($fileEncryptedMessage)) unlink($fileEncryptedMessage);
    if (file_exists ($fileMessageToEncrypt)) unlink($fileMessageToEncrypt);

    return $returnValue;
}

// *************** END OF FUNCTIONS ********************

// Get certificate and private key used for decryption / encryption
$certificate    = file_get_contents("../pathToSomeFolder/certificate.pem", true);
$privateKey     = file_get_contents("../pathToSomeFolder/private_key.pem", true);

$decrypted      = NULL;
$plainMessage   = "Some string that needs to be encrypted";
$cryptoError    = "";

// Attempt to encrypt the plain message and if encryption fails, print the error and exit the script
$encryptedMessage = Encrypt($plainMessage, $certificate, $cryptoError);

if ($encryptedMessage === NULL) {
    echo "Failed to encrypt the plain message, error = $cryptoError";
    exit(1);
} 

// Attempt to decrypt the encrypted message
$decryptedMessage = Decrypt($encryptedMessage, $privateKey, $certificate, $cryptoError);

if ($decryptedMessage === NULL) {
    echo "Failed to decrypt the encrypted message, error = $cryptoError";
    exit(1);
}

echo "Successfully encrypted and decrypted required message";
?>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 13:56:12