I have been running Alpine Linux image version 3.15 with PHP 8.0 with openssl 1.1.x version on my server.
Using this version I have encrypted some data using openssl_pkcs7_encrypt()
function, stored the encrypted data in DB and I was able to then successfully decrypt the encrypted data from DB when needed using openssl_pkcs7_decrypt()
function.
After updating Alpine Linux to 3.17 with PHP to 8.1 which uses openssl 3.0, the openssl_pkcs7_decrypt()
function is unable to decrypt my previously encrypted data which were encrypted using PHP 8.0 with OpenSSL 1.1.x.
I have used openssl_error_string()
function to get all errors reported by OpenSSL library and here's the list of errors reported:
- error:10800077:PKCS7 routines::decrypt error
- error:0308010C:digital envelope routines::unsupported
- last 8 errors are.: error:12000079:random number generator::Cannot open file
I have tried installing openssl1.1-compat
using apk add openssl1.1-compat
as referred in this link as well as I have tried to comment out RANDFILE = $ENV::HOME/.rnd
/etc/ssl/openssl.cnf
as referred to in this post, but unfortunately none of the changes led to any success.
Has anyone faced a similar issue and have you been able to fix this?
Does anyone has any suggestions on what could help me to fix the issue?
Simple code snippet with amended code for data encryption / decryption using the above functions is here:
<?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";
?>