12

私が保守しているPHPアプリケーションは、mcryptを使用したEBC_MODE暗号化を使用したRijndael_256を使用しています。キーの長さは256ビットではなく、160ビットしかないのが楽しいです。ドキュメントによるとmcrypt_encrypt、キーが小さすぎる場合は、必要なサイズを取得するためにキーに\0が埋め込まれます。

データを暗号化するためのキー。必要なキーサイズよりも小さい場合は、「\0」が埋め込まれます。キーにASCII文字列を使用しないことをお勧めします。

これは、mcrypt.cの1186行目の先頭付近で発生し、1213行目のキーを変更しているようです。

短すぎるとしましょう$key = 'abcdefghijkm';。ただし、PHPのmcryptの実装では、RIJNDAEL_256を使用するときに32文字(または256ビット)に拡張されます。最終的なキーはどのようになりますか?

同じ暗号化データを使用しているが、別の言語である別のアプリケーションが構築されているため、これを求めています。正確にはPerlで、私はを使用してCrypto::Rijndaelいます。与えられたサンプルキーの場合、データを再度復号化できるようにするために、私がフィードする必要がある正確なキーCrypto::Rijndael(またはその他のキー)は何ですか?

アップデート

Perlを使用すると、\ 0が埋め込まれたpack('a32', 'my secret key');(またはZ32)キーを生成でき、 length()32を報告し、Crypt::Rijndaelモジュールはキーを受け入れます。PHPのmcryptのソースを見ると、これが生成されているキー(\ 0が埋め込まれている)であるはずですが、それを取得することはできません。

理論的には、PHPではpack('a32', 'my secret key');、PHPのmcryptが生成するのと同じ\ 0の埋め込みキーが生成されるはずですが、そうではありません。

すべてをもう一度暗号化するのに非常に近いですが、新しいキーを使用します。これには時間がかかりすぎます。

4

2 に答える 2

12

問題はキーのパディングではなく、2つの異なるブロックサイズを使用していることです。PHPでは、usingMCRYPT_RIJNDAEL_256は256ビットのブロックサイズを使用します。ただし、perlを使用するCrypt::Rijndael場合、次のように注意します。

blocksize
Rijndaelのブロックサイズは16バイト(128ビット)ですが、アルゴリズムは実際にはバイトの倍数である任意のブロックサイズをサポートしています。ただし、128ビットはAESで指定されたブロックサイズであるため、サポートするのはこれだけです

したがって、これらの異なるアルゴリズム間の変換を可能にするキーはありません。PHPでは128ビットに切り替えることができます。

<?
$key = "abcdefghijklmnopqrstuvwxyz";
$data = "Meet me at 11 o'clock behind the monument.";
$crypttext = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $data, MCRYPT_MODE_ECB, nil);
echo bin2hex($crypttext) . "\n";
// prints c613d1804f52f535cb4740242270b1bcbf85151ce4c874848fd1fc2add06e0cc2d26b6403feef4a8df18f7dd7f8ac67d
?>

Crypt ::Rijndaelを使用して問題なく復号化できるPerl:

use Crypt::Rijndael;
$key = "abcdefghijklmnopqrstuvwxyz\0\0\0\0\0\0";
$crypttext = "c613d1804f52f535cb4740242270b1bcbf85151ce4c874848fd1fc2add06e0cc2d26b6403feef4a8df18f7dd7f8ac67d";
$cipher = Crypt::Rijndael->new($key, Crypt::Rijndael::MODE_ECB());
print $cipher->decrypt(pack('H*', $crypttext));
# prints "Meet me at 11 o'clock behind the monument."

または、より多くのブロックサイズをサポートする別のPerlモジュールに切り替えることができます。たとえば、Crypt :: Rijndael_PP

# Same PHP code except using MCRYPT_RIJNDAEL_256
# prints f38469ec9deaadbbf49bb25fd7fc8b76462ebfbcf149a667306c8d1c033232322ee5b83fa87d49e4e927437647dbf7193e6d734242d583157b492347a2b1514c

Perl:

use Crypt::Rijndael_PP ':all';
$key = "abcdefghijklmnopqrstuvwxyz\0\0\0\0\0\0";
$crypttext = "f38469ec9deaadbbf49bb25fd7fc8b76462ebfbcf149a667306c8d1c033232322ee5b83fa87d49e4e927437647dbf7193e6d734242d583157b492347a2b1514c";
print rijndael_decrypt(unpack('H*', $key), MODE_ECB, pack('H*', $crypttext), 256, 256);
# prints "Meet me at 11 o'clock behind the monument."
于 2012-07-26T23:24:12.257 に答える
4

'\ 0'はNULLを意味し、その16進値は00です!だから私は3つのコードをテストしました、そしてそれらはすべて同じを返しました:)

  1. mcrypt_encryptに「\0」パディングを実行させます
  2. PHPのNULL値で追加
  3. PHPで変換された0の16進値で追加

コード:

function encryptThis($text,$key){
    $iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB);
    $iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
    $crypttext = mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $key, $text, MCRYPT_MODE_ECB, $iv);
    return ($crypttext);
}

echo bin2hex(encryptThis("Meet me at 11 o'clock behind the monument.", "abcdefghijklmnopqrstuvwxyz"))."<br/>";

echo bin2hex(encryptThis("Meet me at 11 o'clock behind the monument.", "abcdefghijklmnopqrstuvwxyz" . NULL . NULL . NULL . NULL . NULL . NULL))."<br/>";

echo bin2hex(encryptThis("Meet me at 11 o'clock behind the monument.", "abcdefghijklmnopqrstuvwxyz" . hex2bin(0) . hex2bin(0) . hex2bin(0) . hex2bin(0) . hex2bin(0) . hex2bin(0)))."<br/>";

?>
于 2012-07-18T13:36:42.583 に答える