我需要使用3DES在Delphi中加密一个10字节的字符串。
它必须得到与此PHP代码相同的结果:
function encrypt_3DES($message, $key){
$bytes = array(0,0,0,0,0,0,0,0);
$iv = implode(array_map("chr", $bytes));
$ciphertext = mcrypt_encrypt(MCRYPT_3DES, $key, $message, MCRYPT_MODE_CBC, $iv);
return $ciphertext;
我一直在尝试使用DCPCrypt和LockBox 3对其进行编码。我终于放弃了DCPCrypt,因为它最近没有更新,我不确定它是否与Delphi 10.1 Berlin正常工作,所以我专注于LockBox 3,但我还没有能够正确加密。
加密密钥是24字节密钥(我有base64表示)。我无法找到如何使用LockBox的TSymetricKey类创建这样的密钥,以将其传递给Codec.Init方法。所以我把它放在AnsiString上并将其设置在Password属性上(尽管文档中说有一个utf8Password但我找不到它。)
然后有一个名为EncryptAnsiString的方法,但是它再次需要字符串(Delphi 10.1柏林上的utf16)而不是AnsiStrings(尽管文档说的相反),所以我并不感到惊讶,结果并没有。匹配我正在寻找的东西(在该PHP片段上加密的相同值)。
这是我的Delphi代码:
function Encrypt(Data: AnsiString; LocalKey: AnsiString): AnsiString;
var
BinaryLocalKey: TBytes;
strLocalKey, strTripleDes: AnsiString;
begin
BinaryLocalKey := DecodeBase64(LocalKey);
setString(strLocalKey, PAnsiChar(@BinaryLocalKey[0]), Length(BinaryLocalKey));
Codec1.Rest;
Codec1.Password := strLocalKey;
Codec1.EncryptAnsiString(Data, strTripleDES);
Codec1.Reset;
Result := strTripleDes;
end;
但是这段代码不仅没有得到与PHP代码相同的结果,而且在每次调用时它都会为同一输入返回不同的结果。
注意:Codec1是链接到TCryptographicLibrary组件的组件,其属性ChainMode设置为CBC *,Cipher设置为3DES(键控选项1)
有人知道如何正确地进行3DES加密吗?
谢谢。
答案 0 :(得分:1)
为每条消息生成随机IV。 IV的低8字节是随机数,高字节是零。这些低8字节前置于输出。
如果要通过侧通道发送IV,则从标称密文中删除前8个字节。
如果要控制IV,请使用版本3.7.0(https://github.com/SeanBDurkin/tplockbox)。您需要设置高级选项并实现OnGetIV方法。
在属性编辑器中呈现的用于密码选择和链模式选择的星号(*)表示此选择是推荐的。