CTR セキュリティでは、同じキーを持つ 2 つのメッセージ暗号化に IV を再利用しないことが要求されます。実際にはさらに厳密です。CTR モードは、カウンターの連続する値を暗号化することによって機能し (IV はそのカウンターの初期値にすぎません)、同じカウンター値が 2 回使用されない場合にのみ、適切なセキュリティが実現されます。これは、IV で値を暗号化すると、別の暗号化で再利用してはならない連続する IV 値のシーケンスを実際に「消費」することを意味します。
これを行う簡単な方法は、暗号的に安全な乱数ジェネレーターを使用し、メッセージごとに新しい 16 バイトのランダム IV を作成することです。「暗号的に安全」に下線を引いたのは、それが重要だからです。基本的な乱数ジェネレーターでは不十分です。Java では、 を使用しますjava.util.SecureRandom
。Win32 では、 を呼び出しますCryptGenRandom()
。ランダムな選択では、可能な 128 ビット IV のスペースが十分に大きいため、衝突が発生する可能性は非常に低くなります。実際、これが AES が 128 ビット ブロックを使用する理由です (つまり、128 ビット IV を意味します)。
メッセージを復号化するエンティティは IV を知っている必要があるため、暗号化されたメッセージと一緒に保存する必要があります。それは余分な 16 バイトです。Cookie の場合、16 バイトはそれほど大きくありませんが、このオーバーヘッドを回避したいことは理解しています。Cookie の有効な最大長は Web ブラウザによって異なりますが、「どこでも」4000 文字が機能するようです。16 バイトの IV は、文字でエンコードされた場合 (たとえば Base64 を使用)、約 22 文字を使用します。つまり、最大 Cookie サイズの 1% よりはるかに少なくなります。
これで、ファンキーになり、策略を使って IV の長さを短くすることができます。
ハッシュ関数を使用して IV を生成します。サーバー側では、0 から始まり、新しい IV が必要になるたびにインクリメントされるカウンターを使用します。IV を取得するには、SHA-256 などの適切なハッシュ関数を使用してカウンターをハッシュし、ハッシュ値の最初の 16 バイトを保持します。ハッシュ関数の「ランダム化プロパティ」は、CTR 要件に関して IV を十分にランダムにするのに十分です。これには、暗号的に安全なハッシュ関数が必要であるため、SHA-256 (MD5 を避ける) が必要です。次に、カウンター値を Cookie に保存するだけで、カウンターは 16 バイトよりも短くなります (たとえば、顧客が 40 億人以下の場合、カウンターは 4 バイトに収まります)。ただし、隠れたコストがあります。サーバー (サーバーがシステムで暗号化を実行していると思います) は、カウンター値を再利用しないようにする必要があるため、"
外部の一意の値を使用します。おそらく、Cookie は、各暗号化に一意の値を生成するのに十分なデータを提供するコンテキストの一部である可能性があります。たとえば、リクエストに「ユーザー ID」も (平文で) 含まれている場合、そのユーザー ID を IV ソースとして使用できます。セットアップは上記のものと似ています。すべてのデータを取得し、SHA-256 に詰め込みます。SHA-256 出力の最初の 16 バイトが必要な IV です。これは、特定の暗号化されたメッセージに対してそのデータが変更されず、それが本当に一意である場合にのみ機能します。これはめったに発生しません: たとえば、「ユーザー ID」は、同じユーザーの新しいメッセージを再暗号化する必要がまったくなく、ユーザー ID が再利用される可能性がない場合にのみ有効です (たとえば、古いユーザーが終了すると、新しいユーザーが来て、現在無料のユーザー ID を選択します)。
暗号的に安全な PRNG で生成されたランダムな 16 バイト IV を使用することは、依然として「安全な」方法であり、私が推奨する方法です。Cookie のスペースが不足している場合、これは 4 kB の制限に近づいていることを意味し、その時点で圧縮を使用することをお勧めします (暗号化前のデータに対して。暗号化後、圧縮が機能する可能性はほとんどありません)。zlibを使用します (Java では、 から zlib にアクセスできますjava.util.zip
)。
警告:上記のすべてにおいて、Cookie 暗号化が達成しようとしているセキュリティ特性を提供するのに役立つかどうかについては何も言っていません。通常、暗号化が必要な場合、実際には暗号化と整合性の両方が必要になるため、暗号化と整合性の組み合わせモードを使用する必要があります。GCMおよびCCMを検索します。さらに、Cookie 暗号化は、サーバー側にユーザー固有のデータを少し保存するコストを回避するという 1 つの目的に適しています。有効なユーザーを認証するなど、別の目的で Cookie を暗号化したい場合、それは間違っています。暗号化はそのための適切なツールではありません。