使用 Python PyCrypto 和 Perl Crypt::CBC

Using Python PyCrypto with Perl Crypt::CBC

一方面我有一个文本 encrypted/decrypted 与 Perl 的 Crypt::CBC

my $key = 'key to the gates'; 
my $cipher = Crypt::CBC->new(
    -key    => $key,
    -cipher => 'Blowfish',
    -salt   => '12341234'  
);

另一方面,我有 Python 的 PyCrypto,我需要从 Perl 解码数据,但也发送 Perl 密码可以在加密的情况下读取的文本。

我有来自 Perl 程序的密钥,以及来自 Perl 的 encrypt_hex:ed 密码短语发送到 Python 系统。

但是 Python 似乎绝对想让 IV 完成它的工作

cipher = Blowfish.new( self.key, Blowfish.MODE_CBC, self.iv )
        return hexlify(cipher.encrypt(raw))

但是,Crypt::CBC 文档似乎表明 IV 已经存在

"salt" -- Combine the passphrase with an 8-byte random value to generate both the block cipher key and the IV from the provided passphrase. The salt will be appended to the beginning of the data stream allowing decryption to regenerate both the key and IV given the correct passphrase.

有没有办法通过 PyCrypto 从 key/passphrase 中提取 IV?或者 IV 是否必须以某种方式单独发送?

这可能是一个幼稚的问题,但我并不是每天都在处理这个问题。

我知道我可以从 Perl 端获取 IV,但如果可能的话,我真的想在 Python 端提取它。

Crypt::CBC 声称兼容 OpenSSL。这意味着它执行 OpenSSL 特定的 BytesToKey 基于密码的密钥派生函数 (PBKDF)。在这个推导过程中,IV 也被计算出来。因此,您为 Crypt::CBC 提供的密钥实际上被视为密码。

您必须查找 EVP_BytesToKey and integrate that into your program. You can start with this code from GitHub:

的实现
def bytes_to_key(data, salt="12345678"):
    # Simplified version of M2Crypto.m2.bytes_to_key(). Based on:
    # https://github.com/ajmirsky/M2Crypto/blob/master/M2Crypto/EVP.py#L105
    # 
    assert len(salt) == 8, len(salt)
    data += salt
    key = md5(data).digest()
    key += md5(key + data).digest()
    return key

然后将第一个字节作为密钥,接下来的 8 个字节作为 IV。但是请注意 Crypt:CBC 的以下语句:

If -keysize is not specified, then Crypt::CBC will use the maximum length Blowfish key size of 56 bytes (448 bits).

因此您可能需要更多 key += md5(key + data).digest() 次调用,因为 md5 输出只有 128 位。