22

次のスクリプトを使用して、一部のデータを暗号化および復号化しようとしています。現在の暗号化が新しいサーバーで機能しないため、これを使用しています。現在mcryptを使っているのでopensslに変更したいです。

私たちのデータベースでは、128 ビット キーを使用する aes 暗号化を使用しているため、キーが何であるかはわかりますが、openssl iv が何であるかはわかりません。そして、なぜ鍵とivが必要なのですか?

私が使用しようとしているコードはこれです。私は暗号化をよく理解していないため、Web サイトで見つけました。

明らかに、キーが別の場所に保持されるように変更します。

function encrypt_decrypt($action, $string) {
    $output = false;

    $encrypt_method = "AES-256-CBC";
    $secret_key = 'This is my secret key';
    $secret_iv = 'This is my secret iv';

    // hash
    $key = hash('sha256', $secret_key);

    // iv - encrypt method AES-256-CBC expects 16 bytes - else you will get a warning
    $iv = substr(hash('sha256', $secret_iv), 0, 16);

    if( $action == 'encrypt' ) {
        $output = openssl_encrypt($string, $encrypt_method, $key, 0, $iv);
        $output = base64_encode($output);
    }
    else if( $action == 'decrypt' ){
        $output = openssl_decrypt(base64_decode($string), $encrypt_method, $key, 0, $iv);
    }

    return $output;
}

$plain_txt = "This is my plain text";
echo "Plain Text = $plain_txt\n";

$encrypted_txt = encrypt_decrypt('encrypt', $plain_txt);
echo "Encrypted Text = $encrypted_txt\n";

$decrypted_txt = encrypt_decrypt('decrypt', $encrypted_txt);
echo "Decrypted Text = $decrypted_txt\n";

if( $plain_txt === $decrypted_txt ) echo "SUCCESS";
else echo "FAILED";

echo "\n";
4

5 に答える 5

25

初期化ベクトルは、CBC (Cipher Block Chaining) モードの AES を機能させるものの一部です。IV は OpenSSL に固有のものではありません。CBC は、前のブロックと現在のブロックを XOR することによって機能します。最初のブロックには前のブロックがないため、IV がその目的を果たします。

なぜこれが必要なのかは、ブロック暗号がどのように機能するかを少し理解する必要があります。この連鎖と IV がなければ、ECB (Electronic Code Book) と呼ばれる AES のモードが残ります。ECB には、他の多くの問題の中でも特に、選択された平文攻撃を可能にする弱点があります。

CBC 初期化ベクトルのベスト プラクティスに少し時間を費やすことをお勧めします。それらを誤って使用すると、AES の全体的なセキュリティが弱まる可能性があります。簡単な説明は次のとおりです。

  • IV はランダムであり、CSPRNG によって生成される必要があります。
  • IV は再使用しないでください。つまり、平文「A」と平文「B」を同じ IV で暗号化しないでください。すべてのレコードには独自の IV が必要です。
  • IV は鍵のような秘密ではありません。暗号文とともに平文で保存できます。

また、このアドバイスは AES-CBC にのみ適用されることに注意してください。GCM など、AES の他のモードを調査する場合、これは当てはまりません。

于 2016-09-09T13:37:59.333 に答える
10

2 人のユーザーが「princess」というパスワードを持っていて、それらをキー「some-key」でエンコードすると、どちらも同じ暗号化結果になります。

| User       | Encrypted password    |
|------------|-----------------------|
| a          | sN7vIFg=              |
| b          | sN7vIFg=              |

つまり、ユーザー a の実際のパスワードが「princess」であり、暗号化されたパスワードが「sN7vIFg=」であるという別の手段を誰かが使用していることが判明した場合、暗号化されたパスワード「sN7vIFg=」を持つすべてのユーザーは、パスワード「princess」を持っていると見なすことができます。 "。

ただし、それぞれにランダムな IV を使用すると、暗号化されたデータにアクセスできる場合、基になるパスワードを推測するのが難しくなります。

| User       | Encrypted password    | IV             |
|------------|-----------------------|----------------|
| a          | sN7vIFg=              | h²ÓIF8]h%L     |
| b          | BjZAzrA=              | VÂøíiøÚØò▓     |

これで、誰かが上記のデータにアクセスできたとしても、ユーザー a と b が同じパスワードを持っていることを知ることはできません。

「本物のソルト」は「初期化ベクトル」と同じですか? も参照してください。.

于 2019-11-19T18:24:58.450 に答える