使用Delphi 10.1 Berlin使用3DES加密字符串

时间:2016-08-09 10:24:53

标签: delphi 3des delphi-10.1-berlin lockbox-3

我需要使用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加密吗?

谢谢。

1 个答案:

答案 0 :(得分:1)

为每条消息生成随机IV。 IV的低8字节是随机数,高字节是零。这些低8字节前置于输出。

如果要通过侧通道发送IV,则从标称密文中删除前8个字节。

如果要控制IV,请使用版本3.7.0(https://github.com/SeanBDurkin/tplockbox)。您需要设置高级选项并实现OnGetIV方法。

在属性编辑器中呈现的用于密码选择和链模式选择的星号(*)表示此选择是推荐的。