2

コードに従う必要があり、私が知る限りそれは正しいですが、機能しません。PHP の Mcrpyt でデータをエンコードしてから、openssl コマンドライン ツールでデコードしようとしています。

これは私のPHPコードです:

/*
 * Convert a normal ascii string to a hexadecimal string.
 * Complement of hexToString().
*/
function stringToHex($str)
{
    $hex_str = "";
    for ($i = 0; $i < strlen($str); ++$i)
    {
        $hex_str .= sprintf("%02X", ord($str[$i]));
    }

    return $hex_str;
}


    $iv = mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC), MCRYPT_DEV_RANDOM);

    $block_size = mcrypt_get_block_size("rijndael-128", "cbc");
    $pad = $block_size - (strlen($data) % $block_size);
    $data .= str_repeat(chr($pad), $pad);

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

    $message = stringToHex($iv) . base64_encode($encrypted);

エンコードされたメッセージに IV を追加します。たとえば、IV が 000000000000000000000000000000 (サイズは 32) の場合、次のコマンドを使用して復号化します。

openssl enc -d -aes-128-cbc -A -nosalt -K 31323334353637383132333435363738 -iv 00000000000000000000000000000000 -in file_in > file_out

また、1234567812345678 は 16 進数であり、31323334353637383132333435363738 であることに注意してください。

不正な復号化 1340:エラー:0606506D:デジタル エンベロープ ルーチン:EVP_DecryptFinal_ex:間違った最終ブロック長:./crypto/evp/evp_enc.c:454:

誰?

前もって感謝します、すべての愛、ジョリ。

4

2 に答える 2

2

さて、私はあなたのコードをテストし、いくつかの変更で動作しました.

1) openssl の入力には、先頭に追加された IV ではなく、暗号文のみを含める必要があります (コードが不完全だったため、openssl で処理する前に暗号文から IV を削除したかどうかはわかりませんでした)。

2) openssl コマンドには、実際に Base64 デコードを行うために必要なパラメーター (-a) がありませんでした (-A を使用しただけでは、これは有効になりません)。繰り返しますが、あなたの説明が不完全だったので、file_in に保存する前にメッセージを実際に Base64 でデコードしたかどうかはわかりませんでした。

完成させるために、これはコードをテストするために使用したコードです (Web サーバーを使用せずに、コマンド ラインから実行します)。

<?php

$data = "
This is a test. This is only a test.
Stack Overflow is collaboratively built and maintained
by your fellow programmers.
";
$keybin = "1234567812345678";


//$iv = mcrypt_create_iv (mcrypt_get_iv_size (MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC), MCRYPT_DEV_RANDOM);
$iv = mcrypt_create_iv (mcrypt_get_iv_size (MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC), MCRYPT_RAND);
$block_size = mcrypt_get_block_size ("rijndael-128", "cbc");
$pad = $block_size - (strlen ($data) % $block_size);
$data .= str_repeat (chr ($pad), $pad);
$encrypted = mcrypt_encrypt (MCRYPT_RIJNDAEL_128, $keybin, $data, MCRYPT_MODE_CBC, $iv);
$message = base64_encode ($encrypted);

echo "CIPHERTEXT=  " . $message . "\n";
echo "IV=  " . bin2hex ($iv) . "\n";
echo "KEY=  " . bin2hex ($keybin) . "\n";

echo "\nTest with:\n\necho $message | openssl enc -d -aes-128-cbc -nosalt -a -A -K " . bin2hex ($keybin) . " -iv " . bin2hex ($iv) . "\n\n";

?>

その他の小さな違いは、PHP の bin2hex を使用したことです。

次のような出力が生成されます。

CIPHERTEXT=  /e81Ua/0jxgff3j5GjKXaNilv5WqPYV7yRYy4AzsTUmGQeK0hcMjuUYp1Yrfthaox9zTI0DeDQT4fba+y/qTQahZpYRAKcZa209RVg4W1HrySfZPMRCxE+y8r8scL3Xmj+oMGFpS+cDo111OPqwHhNwWSHbMlsoJLvMr70ZiQmE=
IV=  56c7c7248c68127cee8f0e54d89b4fc1
KEY=  31323334353637383132333435363738

Test with:

echo /e81Ua/0jxgff3j5GjKXaNilv5WqPYV7yRYy4AzsTUmGQeK0hcMjuUYp1Yrfthaox9zTI0DeDQT4fba+y/qTQahZpYRAKcZa209RVg4W1HrySfZPMRCxE+y8r8scL3Xmj+oMGFpS+cDo111OPqwHhNwWSHbMlsoJLvMr70ZiQmE= | openssl enc -d -aes-128-cbc -nosalt -a -A -K 31323334353637383132333435363738 -iv 56c7c7248c68127cee8f0e54d89b4fc1

発生したエラー (不正な復号化、デジタル エンベロープ ルーチン EVP_DecryptFinal_ex) は、通常、キーが間違っているか、暗号文が破損していることを意味します。あなたの例では、問題は、前に追加された IV および/または Base64 デコードの欠如によって引き起こされた暗号文の破損であったと思います。

于 2012-06-24T08:45:57.300 に答える
1

openssl encデータがブロックサイズの倍数である場合の必須パディングブロックを除いて、あなたが実装したPKCS#5パディングを使用します。16 バイト (ブロック サイズ) でテストするので、chr(16).

于 2012-06-24T08:47:57.053 に答える