I'm trying to decrypt a pass phrase stored in a file. The encryption was done with the Perl::CBC module, but I need to decrypt it for a Python script. Frankly, I don't know much (or anything really) about encryption algorithms.
The pass phrase was encrypted something like this:
use Crypt::CBC;
my $key = '0123456789';
my $iv = '$KJh#(}q';
my $cipher = Crypt::CBC->new(
-key => $key,
-cipher => 'Blowfish',
-header => 'none',
-iv => $iv,
);
my $passphrase = 'You have decrypted the passphrase.';
my $hex_encrypted = $cipher->encrypt_hex($passphrase);
which gives an encrypted passphrase: 9033c838e4418fbdc50a9fc0813745296d195d59954008f94b2b36a8e65dca959686206960a7828a
Now, I need to use this in a Python script (using Python 2.7). Naively, I was hoping this would work:
from Crypto.Cipher import Blowfish
from binascii import hexlify, unhexlify
perl_pass = unhexlify('9033c838e4418fbdc50a9fc0813745296d195d59954008f94b2b36a8e65dca959686206960a7828a')
key = '0123456789'
iv = '$KJh#(}q'
print Blowfish.new(key, Blowfish.MODE_CBC, iv).decrypt(perl_pass)
but that only seems to create a bunch of unprintable junk. I've played around a bit without success. I'm not really sure what I need to do here to get this password decrypted successfully.
The "key" you give to Crypt::CBC is actually a passphrase, from which a 'literal key' is generated; Crypto.Cipher.Blowfish needs that literal key, rather than the passphrase. You can print that generated key in hex from your Perl program, then use it in Python:
use Crypt::CBC;
my $key = '0123456789';
my $iv = '$KJh#(}q';
my $cipher = Crypt::CBC->new(
-key => $key,
-cipher => 'Blowfish',
-header => 'none',
-iv => $iv,
);
my $passphrase = "You have decrypted the passphrase.";
my $hex_encrypted = $cipher->encrypt_hex($passphrase);
print unpack('H*', $cipher->key()), "\n";
-
$ perl perl_crypt_cbc.pl
781e5e245d69b566979b86e28d23f2c78e938564cd1410f0ec1c1781466a6738bab0a6ed984c75ab34c68bbf7558077714043c5bdb959e46
-
from Crypto.Cipher import Blowfish
from binascii import hexlify, unhexlify
perl_pass = unhexlify("9033c838e4418fbdc50a9fc0813745296d195d59954008f94b2b36a8e65dca959686206960a7828a")
key = unhexlify("781e5e245d69b566979b86e28d23f2c78e938564cd1410f0ec1c1781466a6738bab0a6ed984c75ab34c68bbf7558077714043c5bdb959e46")
iv = '$KJh#(}q'
print Blowfish.new(key, Blowfish.MODE_CBC, iv).decrypt(perl_pass)
-
python python_crypt_cbc.py
You have decrypted the passphrase.
Note that there will be a few unprintable characters at the end: Blowfish-encrypted strings must be a multiple of 8 bytes, so Perl silently pads it. The byte it's padded with is the length of the padding: in this case, six bytes of padding, so each of them is 0x06. You can easily remove them:
from Crypto.Cipher import Blowfish
from binascii import hexlify, unhexlify
perl_pass = unhexlify("9033c838e4418fbdc50a9fc0813745296d195d59954008f94b2b36a8e65dca959686206960a7828a")
key = unhexlify("781e5e245d69b566979b86e28d23f2c78e938564cd1410f0ec1c1781466a6738bab0a6ed984c75ab34c68bbf7558077714043c5bdb959e46")
iv = '$KJh#(}q'
num_padding = ord(Blowfish.new(key, Blowfish.MODE_CBC, iv).decrypt(perl_pass)[-1])
print Blowfish.new(key, Blowfish.MODE_CBC, iv).decrypt(perl_pass)[:(-1*num_padding)]