使用PyCrypto解密Perl加密密码

1 投票
1 回答
2624 浏览
提问于 2025-04-17 15:46

我正在尝试解密存储在文件中的密码短语。加密是用Perl::CBC模块完成的,但我需要在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);

这会生成一个加密后的密码短语:9033c838e4418fbdc50a9fc0813745296d195d59954008f94b2b36a8e65dca959686206960a7828a

现在,我需要在一个Python脚本中使用这个(使用Python 2.7)。我天真地希望这样做能成功:

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)

但这似乎只会产生一堆无法打印的垃圾。我尝试了一些方法,但都没有成功。我不太确定该怎么做才能成功解密这个密码。

1 个回答

1

你给Crypt::CBC的“密钥”其实是一个密码短语,从这个短语中会生成一个“真实密钥”;而Crypto.Cipher.Blowfish需要的是真实密钥,而不是这个密码短语。你可以在你的Perl程序中打印出这个生成的密钥,之后在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.

注意,最后会有一些不可打印的字符:Blowfish加密的字符串必须是8字节的倍数,所以Perl会默默地进行填充。填充的字节是填充长度:在这个例子中,填充了六个字节,所以每个填充字节都是0x06。你可以很容易地去掉这些填充:

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)]

撰写回答