我正在使用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为零,则使用ECB加密来从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/CaGYcuEWTfxlI05 as88lJL0mHmJxLsKWqki2YwiFPU9Rx8qiUC2cvWZrQIOnkw==
非常感谢您的帮助。
建议和想法的随机分类:
- 静态IV通常是一种安全风险,因为它们为已知的明文攻击打开了大门
- 从dcpcrypt源来看,似乎有一种方法可以指定IV。如果没有其他原因,除了将不正确的IV作为错误源之外,还有什么理由不这样做吗
- 同样,您可以尝试使用ECB而不是CBC来完全消除IV,并隔离问题是在IV中还是在其他地方(密钥、数据或配置)
免责声明:我是Python的新手,但尝试一下:
尝试更改
key = key[:16]
至
key = key + bytes([0,0,0,0])
这将为您提供一个24字节的密钥,我认为它应该可以工作。
DCP允许任何长度的密钥,而Crypto坚持使用16、24或32字节的密钥。默认情况下,DCP将使用SHA1生成密钥,密钥长度为20字节。基于此,DCP使用密钥长度<=24,并且仅仅零焊键而不是键长度<=的逻辑16,这是键[:16]所具有的效果。
此外,不知道这是否只是打字错误,但尝试更改AES模式
cipher = AES.new(key, AES.MODE_CFB, iv)
至
cipher = AES.new(key, AES.MODE_CBC, iv)
这将对您的输入进行解密。但您需要考虑原始源文本的填充,因为DCP不填充(我认为),但Crypto需要16的倍数才能解密。