3

次の PHP コードを検討してください。

<?php
$key = "1234567812345678";
$iv = "1234567812345678";
$data = "Test string";

$encrypted = mcrypt_encrypt(MCRYPT_RIJNDAEL_128,
                            $key,
                            $data,
                            MCRYPT_MODE_CBC,
                            $iv);

print "Encoded1: " . base64_encode($encrypted) . "\n";

$key = "12345678123456781234567812345678";

$encrypted = mcrypt_encrypt(MCRYPT_RIJNDAEL_128,
                            $key,
                            $data,
                            MCRYPT_MODE_CBC,
                            $iv);

print "Encoded2: " . base64_encode($encrypted) . "\n";

実行すると、次の出力が生成されます。

Encoded1: iz1qFlQJfs6Ycp+gcc2z4w==
Encoded2: n3D26h/m8CSH0CE+z6okkw==

PHP Java AES CBC Encryption Different Resultsからコードの最初のビットを盗んだことに注意してください。

今 - ここに質問があります:

最初のケースでは、渡されたキーは 16 文字の文字列でした。個々の文字のそれぞれが 8 ビット量として解釈された場合、これは 128 ビットの鍵サイズを期待します。実際、上記で参照した StackOverflow ページにある Java コードはまさにそれを実行し、PHP と同じ結果を取得します。

上記の 2 番目の呼び出しmcrypt_encryptでは、キーの長さを 2 倍にしました。 mcrypt_encryptこれを喜んで受け入れますが、最初のケースとは異なる暗号化された出力を生成します。したがって、明らかに、これは別のキーと見なされます。たとえば、最初の 128 ビットのみを取得してそれ以降を破棄することはありません。

では、入力キー文字列をどのように処理して、アルゴリズムが必要 mcrypt_encryptとする 128 ビット キーを生成するのでしょうか?MCRYPT_RIJNDAEL_128

違いがある場合、私が特に関心を持っているのは、2 番目の例のように 32 文字の文字列が渡される場合です。一致する復号化ルーチンを (Java で) 作成する必要があるため、この場合、キーは実際に生成されます。私が引用したページには、完全に優れた Java コード (私のすべてのテスト ケースで動作します) があります。キー バイトの適切なセットが欠けているだけです。

4

1 に答える 1

3

Rijndael アルゴリズムには 2 つの重要なパラメーターがあります。キー サイズ(128 ビット、192 ビット、および 256 ビット) があり、ブロックサイズ(128 ビット、192 ビット、および 256 ビット) があります。128inはMCRYPT_RIJNDAEL_128ブロックサイズを表します。キーのサイズは可変です。

異なる長さのキーを MCrypt に渡すと、適切なキー サイズが自動的に選択されるため、設定することはできません。MCRYPT_RIJNDAEL_128AES(AES-128、AES-192、AES-256)です。もはやAESではMCRYPT_RIJNDAEL_192ありません。MCRYPT_RIJNDAEL_256

Java コードが 128 ビット キーの一致結果を生成した場合、256 ビット キーの一致結果も生成します。

MCrypt は少し奇妙です。PHP バージョン 5.6.0 より前では、128 ビット、192 ビット、または 256 ビットだけでなく、任意のキー長が必要でした。キーは、次の有効なキーの長さまで 0x00 バイトで埋められます。


Java はデフォルトで ZeroPadding をサポートしていないため、PHP の PKCS#5/PKCS#7 パディングなどの適切なパディング スキームを使用する必要があります。この回答には、非常に優れた実装があります。

于 2015-06-09T22:20:08.233 に答える