php和perl 3DES CBC中的返回值相同

时间:2015-11-07 03:09:12

标签: php perl encryption 3des

我想知道如何在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代码中做错了什么?

1 个答案:

答案 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