【发布时间】:2012-03-02 20:18:12
【问题描述】:
我正在尝试使用 DEC 3.0 库 (Delphi Encryption Compedium Part I) 来加密 Delphi 7 中的数据并通过 POST 将其发送到 PHP 脚本,在那里我使用 mcrypt 对其进行解密(RIJNDAEL_256,ECB 模式)。
德尔福部分:
uses Windows, DECUtil, Cipher, Cipher1;
function EncryptMsgData(MsgData, Key: string): string;
var RCipher: TCipher_Rijndael;
begin
RCipher:= TCipher_Rijndael.Create(KeyStr, nil);
RCipher.Mode:= cmECB;
Result:= RCipher.CodeString(MsgData, paEncode, fmtMIME64);
RCipher.Free;
end;
PHP部分:
function decryptMsgContent($msgContent, $sKey) {
return mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $sKey, base64_decode($msgContent), MCRYPT_MODE_ECB, mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB), MCRYPT_RAND));
}
问题是从PHP解密不起作用,输出乱码,与实际数据不同。
当然,Delphi Key 和 PHP $Key 是同一个 24 个字符的字符串。
现在我知道 DEC 3.0 已经过时且过时了,而且我不是加密专家,无法判断实施是否真的是 Rijndael 256。也许有人可以告诉我这个实施与 PHP 的 mcrypt w/RIJNDAEL_256 有何不同.也许密钥大小不同,或者块大小不同,但无法从代码中看出这一点。以下是 Cipher1.pas 的摘录:
const
{ don’t change this }
Rijndael_Blocks = 4;
Rijndael_Rounds = 14;
class procedure TCipher_Rijndael.GetContext(var ABufSize, AKeySize, AUserSize: Integer);
begin
ABufSize := Rijndael_Blocks * 4;
AKeySize := 32;
AUserSize := (Rijndael_Rounds + 1) * Rijndael_Blocks * SizeOf(Integer) * 2;
end;
附加问题:
我知道不推荐使用 ECB 模式,我会在 ECB 工作后立即使用 CBC。问题是,我是否还必须将 Delphi 中生成的 IV 传输到 PHP 脚本?或者知道密钥就足够了,比如欧洲央行?
【问题讨论】:
-
这可能是一个非常愚蠢的问题。但是使用delphi你能解密你的加密数据吗?哦,这个问题的答案有帮助吗:stackoverflow.com/q/8313992/41338
-
你调用 mcrypt_create_iv()。你在 Delphi 中使用的 IV 是什么?
-
@ldsandon:talereader 正在使用 ECB 模式。没有 IV。
-
希望 PHP 知道 - 不知道调用 mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB), MCRYPT_RAND)) 会发生什么;也许它只是被忽略了(我希望),也许它触发了一些不好的事情。如果它返回 False,它可能会将错误的参数传递给 mcrypt_decrypt。
-
@Isandon 想到这一点,通过在加密和解密中生成 IV 来测试 PHP 中的加密/解密,并且输出正常。所以看起来在 ECB 中,mcrypt 忽略了传递的 IV。
标签: php delphi delphi-7 mcrypt rijndael