Home > Software design >  openssl_decrypt fails to decrypt[PHP]
openssl_decrypt fails to decrypt[PHP]

Time:08-03

I am trying to convert a node version of a decryption over to PHP, but i have been stuck with this error - error:0606506D:digital envelope routines:EVP_DecryptFinal_ex:wrong final block length

this is the node.js version of the decryption that is working - https://replit.com/@Olanipekunife/AES-Decryption

this is the php version returning the error

    <?php


$encrypt_method = "aes-256-cbc";
$secret_key = 'test_sk_7JLVA0RNWbOcMVJzzxx0';

$encypted = "714ac730a2eaafb14528f726f21637178d5a09480c1223d66536cd6078b98baab1f9c2efa763797bd00cd04611de62d0";

$encrypted_buffer = unpack('H*', $encypted);
$hex_values = $encrypted_buffer[1];


// echo $hex_values . " \n\n";

$iv = substr($hex_values, 0, 16);

echo $iv . "\n\n";

$final_encrypted_str = substr($hex_values, 16);

$final_key = substr(hash('sha256', $secret_key), 0, 32);

echo $final_key . " key \n\n";



$decryptedData = openssl_decrypt($final_encrypted_str, $encrypt_method, $final_key, 0, $iv);

$err = openssl_error_string();


echo "err \n\n" . $err . "\n\n";
  
echo "decrypted below \n\n" . $decryptedData;

please what am i doing wrong?

CodePudding user response:

The PHP code contains bugs concerning the separation from IV and ciphertext, key derivation, and decryption itself:

  • A simple way to implement the separation is as follows:

    $encryptedBin = hex2bin($encypted);
    $iv = substr($encryptedBin, 0, 16);
    $ciphertext = substr($encryptedBin, 16);
    
  • During key derivation, the current code returns the hash hex encoded instead of Base64 encoded. A correct implementation is:

    $key = substr(base64_encode(hash('sha256', $secret_key, true)), 0, 32);
    

    Note that it is more secure to apply a dedicated key derivation function such as Argon2 or PBKDF2 for key derivation.

  • When decrypting, the current implementation expects the ciphertext to be Base64 encoded and not passed as raw data. A correct implementation is:

    $decryptedData = openssl_decrypt($ciphertext, $encrypt_method, $key, OPENSSL_RAW_DATA, $iv);
    

With these changes, the expected plaintext 5368989195724934 is returned for the posted input data.

  • Related