在 Delphi 和 PHP 中使用 "same" 方法加密时的不同结果
Different results when encrypting with "same" method in Delphi and PHP
我正在尝试在 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 方面我尝试了几个函数来使用相同的密钥 ('test') 加密相同的字符串 ('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 是目前我设法做到的唯一库 运行.
您的 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;
我认为这会对您有所帮助。 TDCP_3des 是块密码,EncryptString
方法使用 EncryptCFB8bit
方法(使用 CFB(8 位)加密方法加密数据的大小字节)。
有两点很重要:
- 使用相同的初始化向量
- 散列 PHP 部分的密钥。
Delphi部分:
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 进行测试。
我正在尝试在 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 方面我尝试了几个函数来使用相同的密钥 ('test') 加密相同的字符串 ('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 是目前我设法做到的唯一库 运行.
您的 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;
我认为这会对您有所帮助。 TDCP_3des 是块密码,EncryptString
方法使用 EncryptCFB8bit
方法(使用 CFB(8 位)加密方法加密数据的大小字节)。
有两点很重要:
- 使用相同的初始化向量
- 散列 PHP 部分的密钥。
Delphi部分:
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 进行测试。