2015-11-07 19 views
2

我想知道如何在perl和php中返回相同的3DES encription值。 PHP代碼如下:在php和perl中返回值相同3DES CBC

$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代碼中做錯了什麼?

回答

2

您沒有使用相同的填充機制。

如果你讀的PHP's mcrypt_encrypt參考頁非常仔細,你會看到旁邊的數據參數,下面的註釋:

如果數據的大小不是n *塊大小,數據將被填充與'\ 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, ''); 

或者你可以實現PKCS#5在PHP中,你必須自己做,因爲PHP默認情況下不包括它(搜索PHP PKCS#5你可能會找到一些可以使用的代碼片段,甚至可以在其中一個PHP-doc註釋中使用simple PKCS#5 function)。

+1

請注意,對於任何可能包含NUL的字符串(即幾乎任何「二進制」文件),PHP的填充方法都是不安全的。 – ikegami

+0

這是有趣的@ikegami!謝謝(你的)信息 –