如何恢复使用 3DES 加密由 OpenSSL 加密的文件的密钥和 iv?

问题描述

我知道有一些类似问题的答案,但这些似乎仅适用于 AES 加密,当我使用 python 进行密钥推导时,我得到了不同的结果。

现在我有了密码和盐(来自以前使用 3DES 的 OpenSSL 加密文件)。我可以简单地通过 OpenSSL 计算密钥和 iv,但我想将密钥派生实现到我的 python 中。

这是来自 OpenSSL 的输出,我相信在使用 python 进行密钥派生后我应该得到相同的结果:

# openssl enc -des3 -pass pass:cfe4ec9fcec928d51d243855a094b05ebb7bc870 -S 3AA6A64F87764632 -P
salt=3AA6A64F87764632
key=6A8E552A81763B15EC9E1430FAB774C7B5113AFD89E6F03C
iv =DE2CFC91DC61E734

我在我的 python 中使用了这段代码

...
print("password is",password.hexdigest())
...
D1=hashlib.md5(password.digest() + openssl_salt).digest()
D2=hashlib.md5(D1 + password.digest() + openssl_salt).digest()
D3=hashlib.md5(D2 + password.digest() + openssl_salt).digest()
key=D1+D2
iv=D3
print ('salt:',openssl_salt.hex())
print ('key:',key.hex())
print ('iv:',iv.hex())

这是我的结果,明显不同,key/iv长度也有问题:

password is cfe4ec9fcec928d51d243855a094b05ebb7bc870
...
salt: 3aa6a64f87764632
key: 49096a6dca92f70c88e92a9d67062b8ae70223e432e23a4ee9abd3531d35e1aa
iv: 964f7299c4b960a1264863a23fbbf20b

我认为这些代码可能用于 AES 密钥推导,而不是用于 3DES。谁能给点建议?

解决方法

查看 openssl enc 使用的 KDF 的 this postdocumentation,您似乎非常接近解决方案。

  1. 密码 cfe... 只是作为 ASCII 文本编码为字节,而不是十六进制字符串。
  2. key 是 24 字节,IV 是 8,MD5 摘要是 16,所以我们只需要两轮。

组合起来:

>>> password = 'cfe4ec9fcec928d51d243855a094b05ebb7bc870'.encode()
>>> salt = bytes.fromhex('3AA6A64F87764632')
>>> d1 = hashlib.md5(password+salt)
>>> d2 = hashlib.md5(d1.digest()+password+salt)
>>> keymatter = d1.digest() + d2.digest()
>>> key = keymatter[:24].hex().upper()
>>> iv = keymatter[24:32].hex().upper()
>>> print(f'key: {key}\nIV:  {iv}')
key: 6A8E552A81763B15EC9E1430FAB774C7B5113AFD89E6F03C
IV:  DE2CFC91DC61E734

,

如果您喜欢没有外部库的纯 Python 解决方案,请使用 Tom Tang 在其 GitHub Gist https://gist.github.com/tly1980/b6c2cc10bb35cb4446fb6ccf5ee5efbc 上提供的方法。

输出将是:

Correct_Weight

完整源代码:

is_weight_faulty = 1