2016-11-19 13 views
1

JavaScriptにPHP暗号化スクリプトを実装しようとしています。私のPHPスクリプトは128文字の文字列を返しますが、Javascriptベースのものは160文字を返します。 JavaScriptベースのバージョンの最初の128文字は、PHPベースのバージョンと一致します。Javascript AES暗号化が多すぎる文字を返す

function pkcs5_pad ($text, $blocksize){ 
    $pad = $blocksize - (strlen($text) % $blocksize); 
    return $text . str_repeat(chr($pad), $pad); 
} 
$skey = "somekey"; 
$ivKey = "someIVKey"; 
$input = "empid=xxxxxx;timestamp=Sat, 19 Nov 2016 00:33:03 UTC"; 

try { 
    $size = mcrypt_get_block_size(MCRYPT_RIJNDAEL_128,'cbc'); 
    echo strlen($input) . "\n"; 
    $input = pkcs5_pad($input, $size); 
    echo strlen($input) . "\n"; 
    $cipher = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', MCRYPT_MODE_CBC, ''); 

    $key = pack('H*', $skey); 
    $iv = pack('H*', $ivKey); 
    # The key size used is 16, 24 or 32 bytes - for AES-128, 192 and 256 respectively 

    if (mcrypt_generic_init($cipher, $key, $iv) != -1){ 
    $encrypted = mcrypt_generic($cipher, $input); 
    mcrypt_generic_deinit($cipher); 
    $encryptedString = bin2hex($encrypted); 
    } 
    echo $encryptedString . "\n"; 
    echo strlen($encryptedString) . "\n"; 
} catch (Exception $ex) { 
    echo $ex->getMessage(); 
} 

ここでは、長さstrlen($encryptedString)は128文字です。

私はJavaScriptベースのバージョンは前とpkcs5_pad後の文字列な長さを含めて、すべてが一致し、この

var aesKey = "somekey"; 
var ivKey = "someIVKey"; 

function pkcs5_pad (text, blocksize){ 
    console.log(text.length); 
    var pad = blocksize - (text.length % blocksize); 
    console.log("pad:" + pad); 
    return text + str_repeat(chr(pad), pad); 
} 

input = "empid=xxxxxx;timestamp=Sat, 19 Nov 2016 00:33:03 UTC"; 

var size = 16; 
console.log(input.length); 
var input = pkcs5_pad(input, size); 
console.log('"' + input + '"'); 
console.log(input.length); 

var key = CryptoJS.enc.Hex.parse(aesKey); 
var iv = CryptoJS.enc.Hex.parse(aesIV); 

var encryptedString = CryptoJS.AES.encrypt(input,key,{iv: iv}); 
console.log(encryptedString.ciphertext.toString().length); 
encryptedString = encryptedString.ciphertext.toString(); 

のようなルックスを作成するためにCryptoJSを使用しています。私はlocutus.ioからstr_repeatとchrを呼び出すためにいくつかの追加のJavaScriptコードを使用しています。ここでencryptedString.ciphertext.toString().lengthは160文字を返し、最初の128文字はPHPスクリプトのものと一致します。

CryptoJSのバージョン3はCBCモードを使用していると私は理解していますが、モードを明示的にCBCに設定しても無駄です。私は暗号化された文字列も16進数として返しました

encryptedString = encryptedString.ciphertext.toString(CryptoJS.enc.Hex); 

どこが間違っていますか?

EDIT JavaScriptバージョンの出力である PHPバージョンの出力である

86b1c9874069129d0852eade01eb753a176a1c6155c4af3ac447ae0a5350b92c3447f95be9c4f8cdbf14503696bcaa16e6307c1605a2cac503239db9d1ac6fb3

86b1c9874069129d0852eade01eb753a176a1c6155c4af3ac447ae0a5350b92c3447f95be9c4f8cdbf14503696bcaa16e6307c1605a2cac503239db9d1ac6fb33051208849788f8a90db1cbe2494cac7

+0

出力はどのように見えるのですか? – Sammitch

+0

出力が質問に追加されました – Robbert

+0

mcryptを使用しないことをお勧めします。これは10年近く前から放棄されました。このため、PHP 7.2では非推奨となり、コアからPECLに削除されます。標準のPKCS#7(néePKCS#5)パディングはサポートされていません。バイナリデータでも使用できない非標準のヌルパディングのみがサポートされています。 mcryptには、2003年にさかのぼる多くの傑出した[バグ](https://sourceforge.net/p/mcrypt/bugs/)があります。代わりに[defuse](https://github.com/defuse/php-encryption)の使用を検討するか、 [RNCryptor](https://github.com/RNCryptor)は、完全なソリューションを提供し、維持管理されており、正しいものです。 – zaph

答えて

1

余分な32文字は16バイトの16進符号化であり、それはパディングです。 Javaはパディングを追加していますが、PHPはそうではありません。

mcryptは、標準のPKCS#7(néePKCS#5)パディングを使用しないことに注意してください。

優れた暗号化ライブラリにはパディングオプションがあり、パディングを暗号化に追加して解読時に削除します。自分のパディングをする必要はありません。