我想知道如何在perl和php中为3DES encription返回相同的值。 PHP代码如下:
$bytes = array(0,0,0,0,0,0,0,0);
$iv = implode(array_map("chr", $bytes));
$ciphertext = mcrypt_encrypt(MCRYPT_3DES, base64_decode('Mk9m98IfEblmPfrpsawt7BmxObt98Jev'), '0000001920', MCRYPT_MODE_CBC, $iv);
echo base64_encode($ciphertext);
结果是:" A / VCTXA6q / x / emW0zzlSDg =="
perl代码是:
use Crypt::CBC;
$cipher = Crypt::CBC->new( -key => decode_base64('Mk9m98IfEblmPfrpsawt7BmxObt98Jev'),
-cipher => 'DES_EDE3',
-iv => pack("H*","0000000000000000"),
-literal_key => 1,
-header => 'none'
);
$ciphertext = $cipher->encrypt("0000001920");
print encode_base64($ciphertext, '');
结果是:" A / VCTXA6q / y9g7ypgqlWIg =="
结果非常相似,我在perl代码中做错了什么?
答案 0 :(得分:2)
您没有使用相同的填充机制。
如果您仔细阅读PHP's mcrypt_encrypt的参考页面,您会在数据参数旁边看到以下注释:
如果数据大小不是n * blocksize,则数据将用'\ 0'填充。
现在,如果您还阅读了Perls Crypt::CBC的参考页面,您会发现它们有多种填充方法(由-padding
参数定义)。默认值为PKCS#5,这与仅使用0x00
填充不同。
现在,如果将填充更改为"null"
,Perl将打印与PHP相同。所以你的代码应该是这样的:
use MIME::Base64;
use Crypt::CBC;
$cipher = Crypt::CBC->new( -key => decode_base64('Mk9m98IfEblmPfrpsawt7BmxObt98Jev'),
-cipher => 'DES_EDE3',
-iv => pack("H*","0000000000000000"),
-padding => "null",
-literal_key => 1,
-header => 'none'
);
$ciphertext = $cipher->encrypt("0000001920");
print encode_base64($ciphertext, '');
或者您可以在PHP中实现PKCS#5,您必须自己完成,因为默认情况下PHP不包含它(搜索PHP PKCS#5并且您可能找到一些可以使用的代码片段,theres甚至是其中一篇PHP-doc评论中的simple PKCS#5 function。