【问题标题】:Different results when encrypting with "same" method in Delphi and PHP在 Delphi 和 PHP 中使用“相同”方法加密时的不同结果
【发布时间】:2020-08-15 16:54:15
【问题描述】:

我正在尝试在 Delphi 和 PHP 之间交换加密消息。

在 Delphi 方面,我从这里下载了 DCPcrypt v2 Beta 3:

http://www.cityinthesky.co.uk/opensource/dcpcrypt/

为了加密,我使用这个函数:

function TForm1.Encrypt3DES(psData, psKey: string): string;
var
  Cipher: TDCP_3des;
begin
  Cipher:= TDCP_3des.Create(nil);
  Cipher.InitStr(psKey,TDCP_sha256);
  result:=Cipher.EncryptString(psData);
  Cipher.Burn;
  Cipher.Free;
end;

我正在这样测试它:

ShowMessage(Encrypt3DES('test','SecretKeySecretKeySecret'));

我得到的结果是Z74E0Q==,我可以用另一个类似的delphi函数成功解密:

function TForm1.Decrypt3DES(psData, psKey: string): string;
var
  Cipher: TDCP_3des;
begin
  Cipher:= TDCP_3des.Create(nil);
  Cipher.InitStr(psKey, TDCP_sha256);         
  result:=Cipher.DecryptString(psData);
  Cipher.Burn;
  Cipher.Free;
end;

在 PHP 方面,我尝试了几个函数来使用相同的密钥('SecretKeySecretKeySecret')加密相同的字符串('test'),但结果与我在 Delphi 中得到的不同。同样,我可以使用类似的功能成功解密 PHP 中的消息,但我需要在 Delphi 中解密消息。

这就是我在 PHP 中所做的,我什至尝试对密钥进行哈希处理,因为我看到 Delphi 函数正在使用 TDCP_sha256,但结果仍然不同。

$key = "SecretKeySecretKeySecret";

echo base64_encode(mcrypt_encrypt(MCRYPT_3DES, $key, 'test', 'ecb')).'<BR><BR>';

echo openssl_encrypt('test', 'des-ede3', $key).'<BR><BR>';

$key = hash('sha256', $key);
echo openssl_encrypt('test', 'des-ede3', $key).'<BR><BR>';

这是结果:

Z05z5Bp4/vY=

L5qmk5nJOzs=

bm7yRdrMs5g=

我做错了什么?顺便说一句,我使用的是 Delphi 7,而 DCPcrypt 是目前我设法让它运行的唯一库。

【问题讨论】:

  • 在 Delphi 7 中使用 AnsiString(8 位(ANSI)字符)。 PHP中使用什么类型的字符串?如果使用 Unicode 字符串,加密的结果会有所不同。
  • @ValMarinov 这是一个很好的建议,但似乎情况并非如此。我在 Delphi 中使用了 UTF8String('test'),它并没有改变结果。然后我在 PHP 中使用了 $text = iconv("UTF-8", "Windows-1252", "test") 并且没有任何变化。我什至在 Delphi 和 PHP 中都转换了密钥,但我得到了相同的结果。
  • 看起来不像那些函数会做同样的事情。为什么您决定以这种方式编写代码,或者您只是从一些在线资源中复制代码而没有真正了解所有含义?

标签: php delphi delphi-7


【解决方案1】:

我认为这会对您有所帮助。 TDCP_3des 是块密码,EncryptString 方法使用EncryptCFB8bit 方法(使用CFB(8 位)加密方法加密大小字节的数据)。

有两点很重要:

  • 使用相同的初始化向量
  • 在 PHP 部分中散列密钥。

德尔福部分:

function TForm1.Encrypt3DES(psData, psKey: string): string;
var
   Cipher: TDCP_3des;
   i: integer;
begin
   Cipher := TDCP_3des.Create(nil);
   try
      Cipher.InitStr(psKey, TDCP_sha256);
      Cipher.SetIV('00000000');
      Result := Cipher.EncryptString(psData);
      Cipher.Burn;
   finally
      Cipher.Free;
   end{try};
end;

procedure TForm1.btnEncryptClick(Sender: TObject);
var
   input, key: string;
begin
   input := 'Some words in English';
   key   := 'SecretKeySecretKeySecret';
   ShowMessage(Encrypt3DES(input, key));
end;

PHP部分:

<?
$key = "SecretKeySecretKeySecret";
$key = hash('sha256', $key, true);
$key = substr($key, 0, 24);
$iv = '00000000';

$message = 'Some words in English';
$result = mcrypt_encrypt(MCRYPT_3DES, $key, $message, MCRYPT_MODE_CFB, $iv);
$result = base64_encode($result);
echo 'Input text: '.$message.'</br>';
echo 'Encrypted text: '.$result.'</br>';
?>

输出:

Input:          Some words in English                           
Encrypted text: hTpdn+USolFTgv/4HnBEvo4scgmp
Input:          This will test Delphi7 and PHP encryption.
Encrypted text: gik2Iw/m2rtMA9gdKqvFqDg3kuUSb4rnAieyZ8unIvt510Rbt1jLPO+/      
Input:          I hope this will work.                          
Encrypted text: n/JxW12zORaI7TSCAF4/6cBxqC3mZg== 

注意事项:

使用 Delphi 7、DCPcrypt v2、PHP 5.2.10、mcrypt 2.5.7 测试。

【讨论】:

    【解决方案2】:

    base64 密文的长度表明 DCPCrypt 不使用 ECB。使用最小的程序,我可以重现您的结果,并且单步执行代码确实表明 ECB 未使用。相关部分是

    function TDCP_blockcipher.EncryptString(const Str: string): string;
    begin
      SetLength(Result,Length(Str));
      EncryptCFB8bit(Str[1],Result[1],Length(Str));
      Result:= Base64EncodeStr(Result);
    end;
    
    function TDCP_blockcipher.DecryptString(const Str: string): string;
    begin
      Result:= Base64DecodeStr(Str);
      DecryptCFB8bit(Result[1],Result[1],Length(Result));
    end;
    

    【讨论】:

    • 谢谢,我应该看到这个。不幸的是,我看不到如何在 Delphi 中添加 iv 向量。在 PHP 中它是一个参数。
    • @georgi-bonchev:欧洲央行不使用静脉注射。但请注意不同的填充模式。 (无论如何设置IV使用TDCP_blockcipher64.SetIV(const Value);
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多