Reputation: 125
I am trying to use openssl on linux bash to decrypt the data generated by PHP code
I tried by passing -base64 -A, and mentioning -md sha256 after reading related questions on stackoverflow. But nothing worked.
$output = false;
$encrypt_method = "AES-256-CBC";
$secret_key = "KEY";
$secret_iv = "KEY";
$string = "123456789ABCDEF";
$key = hash('sha256', $secret_key);
// iv - encrypt method AES-256-CBC expects 16 bytes - else you will get a warning
$iv = substr(hash('sha256', $secret_iv), 0, 16);
$output = openssl_encrypt($string, $encrypt_method, $key, 0, $iv);
echo $output;
?>
NAMQy8pB7ZTjPacExtMBsg==
Then I tried to decrypt on linux:
echo "NAMQy8pB7ZTjPacExtMBsg==" |openssl enc -base64 -d -aes-256-cbc -K 905e17d5f5e4939d48bd04ff47f9de906375b87b67068b2ce5d1bbbbc8dca291 -iv 905e17d5f5e4939d -p
salt=0000000000000000
key=905E17D5F5E4939D48BD04FF47F9DE906375B87B67068B2CE5D1BBBBC8DCA291
iv =905E17D5F5E4939D0000000000000000
bad decrypt
140500719368080:error:06065064:digital envelope routines:EVP_DecryptFinal_ex:bad decrypt:evp_enc.c:592:
PHP Version :7.3.10
Openssl version on linux bash: OpenSSL 1.0.2k-fips 26 Jan 2017
I am expecting it to decrypt the data as I am passing the same key/iv. what am I doing wrong here?
Upvotes: 1
Views: 1661
Reputation: 49141
The PHP-function hash
has a 3rd parameter ($raw_output
) that controls the format in which the result is returned. If the parameter is FALSE
, the result is returned as a hexadecimal string (in lower case). This is the default. If the parameter is TRUE
, the result is returned as binary string.
With regard to the use of the parameters $key
and $iv
in the openssl_encrypt
-call, I suspect that the result should be returned as binary string. Therefore the current PHP-code must be modified and the value TRUE
must be passed as 3rd parameter in the hash
-function for both key and IV.
To display key and IV as hexadecimal strings (with regard to the OpenSSL-statement), use the PHP-function bin2hex
.
This results in:
Key (hex): d7964f06c187b9ba129b0b9fd3db673fc8f83348e8fde4db339034c1944b89de
IV (hex): d7964f06c187b9ba129b0b9fd3db673f
Output (Base64): vf6mWjgdOsBS2qE9U3/VCA==
If you use this result in the OpenSSL-statement:
echo vf6mWjgdOsBS2qE9U3/VCA== | openssl enc -base64 -d -aes-256-cbc -K d7964f06c187b9ba129b0b9fd3db673fc8f83348e8fde4db339034c1944b89de -iv d7964f06c187b9ba129b0b9fd3db673f
the decryption is successful.
Update:
If the PHP-code can't be modified, key and IV used in the OpenSSL-statement must be modified: In the posted code, the 32-bytes-key is expressed as a hexadecimal string, i.e. with 64 characters or 64 bytes. Of these, openssl_encrypt
only considers the first 32 bytes, i.e. the actual key is:
$key = substr(hash('sha256', $secret_key), 0, 32);
The IV is still:
$iv = substr(hash('sha256', $secret_iv), 0, 16);
To display key and IV as hexadecimal strings (with regard to the OpenSSL-statement) bin2hex
must be used as before and it results:
Key (hex): 6437393634663036633138376239626131323962306239666433646236373366
IV (hex): 64373936346630366331383762396261
Output (Base64): NAMQy8pB7ZTjPacExtMBsg==
The OpenSSL-statement:
echo NAMQy8pB7ZTjPacExtMBsg== | openssl enc -base64 -d -aes-256-cbc -K 6437393634663036633138376239626131323962306239666433646236373366 -iv 64373936346630366331383762396261
decrypts the ciphertext successfully.
Upvotes: 2