1

我正在使用 Rijndael 解密使用 DCPcrypt 加密的数据。我想用 Python 来解密它,但我遇到了问题。我会提到我不是特别精通加密(我参加了大学课程,但仅此而已)而且我也不是 Delphi 程序员,所以这也可能阻碍我努力破译 DCPcrypt 正在做什么。

这是 Delphi 代码的核心:

Cipher: TDCP_rijndael;
begin
Cipher:= TDCP_rijndael.Create(nil);
Cipher.InitStr(PasswordField.Text);
Cipher.EncryptCBC(encryptString[1],encryptString[1],Length(encryptString));

因此,该实现使用密钥(从密码字段获得)但没有 IV。另一方面,PyCrypto 需要 IV。搜索 DCPcrypt 代码的内部,似乎如果 IV 为 nil,则使用 E​​CB 加密从 0xff 字符串填充 IV?

procedure TDCP_rijndael.Init(var Key; Size: longint; IVector: pointer);
....
  if IVector= nil then
  begin
    FillChar(IV,Sizeof(IV),$FF);
    {$IFDEF CFORM}Encrypt(IV,IV){$ELSE}RijndaelEncryptECB(Data,IV,IV){$ENDIF};
    Move(IV,LB,Sizeof(LB));
  end

看来我正在使用静态 IV。但是,我无法完成这项工作。这是我在 PyCrypto 中的实现。任何想法我做错了什么?

key = "password"
s = hashlib.sha1()
s.update(key)
key = s.digest()
key = key[:16]

# Set up the IV, note that in ECB the third parameter to the AES.new function is ignored since ECB doesn't use an IV
ecb = AES.new(key, AES.MODE_ECB, '\xff' * 16)
iv = ecb.encrypt('\xff' * 16)

cipher = AES.new(key, AES.MODE_CFB, iv)
msg = cipher.decrypt(ct[:16])

我有一些使用 Delphi 代码加密然后 base64 编码的纯文本。使用的密钥是字符串密码,如上面的硬编码。使用我的实现,我解密了一堆乱码。

k8b+uce5Fkp7Hbk/CaGYcuEWTfxlI05as88lJL0mHmJxLsKWqki2YwiFPU9Rx8qiUC2cvWZrQIOnkw==

任何帮助是极大的赞赏。

4

2 回答 2

0

随机的各种建议和想法:

  1. 静态 IV 通常存在安全风险,因为它们为已知的明文攻击打开了大门。
  2. 查看 dcpcrypt 源代码,似乎有一种方法可以指定 IV。如果没有其他原因,除了消除不正确的 IV 作为错误源之外,还有什么理由不这样做?
  3. 同样,您可以尝试使用 ECB 而不是 CBC 来完全消除 IV 并隔离问题是在 IV 中还是在其他地方(密钥、数据或配置)。
于 2012-09-12T05:13:48.327 回答
0

免责声明:我对 Python非常

陌生,但试试这个: 尝试改变

key = key[:16]

key = key + bytes([0,0,0,0])

这将为您提供一个 24 字节的密钥,我认为它应该可以工作。

DCP 允许任何长度的密钥,而 Crypto 坚持使用 16、24 或 32 字节的密钥。默认情况下,DCP 将使用 SHA1 生成密钥,密钥长度为 20 字节。基于此 DCP 使用 keylength <= 24 的逻辑,并且只填充密钥而不是 keylength <= 16 的逻辑,这是 key[:16] 所具有的效果。

另外,不知道这是否只是一个错字,但尝试更改 AES 模式

cipher = AES.new(key, AES.MODE_CFB, iv)

cipher = AES.new(key, AES.MODE_CBC, iv)

这将解密您的输入。但是随后您需要考虑对原始源文本进行填充,因为 DCP 不填充(我认为),但 Crypto 需要 16 的倍数进行解密。

于 2012-09-13T14:13:59.763 回答