My encryption/decryption environment works fine in Perl. Reading that information from php is my problem I am seeking an answer for. Below is my test case, I'd like the php to print $decryption correctly. Currently I get a blank.
#(perl 5) the encryption method
use Crypt::Blowfish;
use Crypt::CBC;
$cipher = Crypt::CBC->new( -key => "example",
-cipher => 'Blowfish',
-iv => '12345678',
-header => 'none'
);
$pj="Testing encryption";
$pje = $cipher->encrypt("$pj");##
$pjf = unpack("H*", $pje), "\n";
open (FILE2,">data.txt");
print FILE2 "$pjf";
close (FILE2);
#(php 7.3)
<?php
$data = file_get_contents("data.txt");
$encryption = pack("H*", $data);
$ciphering = "blowfish";
$options = 0;
// Display the encrypted string
echo "Encrypted String: " . $encryption . "\n";
// Non-NULL Initialization Vector for decryption
$decryption_iv = '12345678';
// Store the decryption key
$decryption_key = "example";
// Use openssl_decrypt() function to decrypt the data
$decryption=openssl_decrypt ($encryption, $ciphering,
$decryption_key, $options, $decryption_iv);
// Display the decrypted string
echo "Decrypted String: " . $decryption;
echo""
?>
(thank You)
When the Crypt::CBC
object is created in the Perl code, the following is defined with regard to the key, see here:
-keysize
argument isn't specified, the key has the maximum size of 56
bytes.-literal_key
argument isn't specified, the value is interpreted as a passphrase and the actual key is derived from it (usually in combination with a salt).-salt
argument isn't specified, no salt is used, so the key is derived only from the passphrase.For the example in the posted Perl code the ciphertext as hexadecimal string ($pjf
) is:
ecc9d0b2449ef433285ade2d02ac19184866f5f9b814bde2
To successfully decrypt this ciphertext with the posted PHP code, the following changes are necessary:
The key must be derived from the passphrase. This is done in the expandKey
function. The key is generated by creating the MD5 hash of the passphrase. If the key doesn't have the required length, it's hashed again and appended to the previous hash. This happens until a key with the required length has been generated.
The OPENSSL_RAW_DATA
flag must be set, because the encrypted data are passed to openssl_decrypt
as raw data and not Base64 encoded. Alternatively, the encrypted data must be passed Base64 encoded to openssl_decrypt
.
PHP code including changes:
$encryptedDataHex = 'ecc9d0b2449ef433285ade2d02ac19184866f5f9b814bde2';
$encryptedData = hex2bin($encryptedDataHex);
$key = expandKey('example');
$iv = '12345678';
$cipher = 'bf-cbc'; // 'blowfish' also works
$options = OPENSSL_RAW_DATA;
$decryptedData = openssl_decrypt($encryptedData, $cipher, $key, $options, $iv);
echo 'Decrypted data: ' . $decryptedData;
function expandKey($key){
$key = md5($key, true);
while(strlen($key) < 56){
$key .= md5($key, true);
}
return substr($key, 0, 56);
}