DES、3DES、RC4、Blowfish をゼロから解説
一言で言えば:この 4 つの暗号は 1990 年代の主力でした — DES とその 3 重暗号化の回避策 3DES、ストリーム暗号 RC4、そして Blowfish — 今ではすべて引退または非推奨で、読み続けなければならない古いファイル、古いハードウェア、古いプロトコルによってだけ生かされています。
DES:すべてを始めた 1977 年の標準
とは。Data Encryption Standard(FIPS 46、1977 年)は 64 ビットブロックの 16 ラウンド Feistel 暗号で、56 ビット鍵を持ちます(各バイトの 1 ビットがパリティチェックのため 8 バイトに格納)。IBM が NSA の関与のもとで設計し、20 年間米国標準でしたが、1998 年に EFF の Deep Crack マシンが 25 万ドルのハードウェアで 56 時間の総当たりで鍵を破り、ポリシー上で破られました。NIST は 2005 年に暗号化用途から撤退させました。
パリティビットが鍵長を混乱させる理由。DES 鍵の 8 ビットごとに 1 ビットは他の 7 ビットから計算されるため、8 バイトの鍵が持つ独立ビットは 56 だけです — 同じ暗号に「64 ビット鍵」と「56 ビット鍵」の両方の表記が見られる理由です。3DES はこれを引き継ぎます:24 生バイト = 168 生ビット = 実効 112 ビット(中間者攻撃が残りを削ります)。
今も出会う場所。銀行の PIN ブロック(ISO 9564)、一部の Kerberos v4 レルム、古いバックアップアーカイブ、スマートカード。今日システムが DES を要求するなら、1990 年代のハードウェアと相互運用しているか、単に安全でないかのどちらかです。
3DES:暗号化、復号、暗号化
トリック。Triple-DES は各ブロックに DES を 3 回走らせます:EDE3 は 3 つの異なる鍵を使い(C = Ek3(Dk2(Ek1(P))))、中間の復号ステップは k1=k2 とすれば 3DES 実装が単一 DES をエミュレートできるように存在します。EDE2 は 2 つの鍵だけ(k1=k3)で実効 112 ビットを与えます。この構造は、すでに攻撃された暗号に新しいものを発明せずにセキュリティを 3 倍にする応急処置でした。
それでも死んだ理由。2 つの問題:遅い(ブロックあたり 3 回の完全な DES パス、AES の約 1/20 の速度)で、64 ビットブロックを保持し続けたことです。1 つの鍵の下で 32 GiB のデータ(232 ブロックの誕生日限界)を超えると、ブロック衝突が平文の構造を漏らすほど起こり得ます — Sweet32 攻撃(2016 年)が TLS の 3DES セッションに対して実証しました。NIST は 2023 年以降 3DES 暗号化を禁止し(SP 800-131A r2)、PCI DSS は決済システムからの引退を要求しています。
RC4 / ARCFOUR:初期 Web のストリーム暗号
仕組み。RC4(Ron’s Code 4、1987 年設計、1994 年漏洩)はストリーム暗号です:鍵が 256 バイトの置換を初期化し(KSA)、その置換が疑似ランダムなバイトストリームを吐き出し(PRGA)、メッセージと XOR されます。パディングなし、ブロックサイズなし、任意のメッセージ長、ソフトウェアで桁違いに速い — だからこそ 1990 年代の SSL/TLS と WEP を支配しました。「ARCFOUR」は商標フリーの名前で、ほとんどのオープンソースプロジェクトが使います。
破られた方法。Fluhrer-Mantin-Shamir(2001 年)は鍵ストリームの最初のバイトに偏りがあることを示しました — パケットごとの鍵構造がそのバイトを攻撃者に与える WEP では致命的でした。後の偏り攻撃(2013 年、AlFardan ら)は数百万の接続から RC4 保護の TLS セッションから平文を復元しました。RFC 7465(2015 年)は TLS での RC4 を完全に禁止しました。
古典ベクトル。鍵「Key」(3 バイト)、メッセージ「Plaintext」は暗文 bbf316e8d940af0ad3 を与えます — RC4 のサンプルを試して比較してください。このページのセルフテストは 40 ビット鍵 01 02 03 04 05 の RFC 6229 鍵ストリームもチェックします:b2396305f03dc027ccc3524a0a1118a8。
Blowfish:破られていない、しかしブロックが制限
とは。Bruce Schneier の 1993 年の Feistel 暗号:64 ビットブロック、32〜448 ビット(4..56 バイト)の鍵、16 ラウンド、そしてサブ鍵を作るために Blowfish 自身を 521 回走らせる有名な鍵スケジュール — 鍵のセットアップは遅いが総当たりも高くつきます。フルラウンドの Blowfish を破る実用的な暗号解析はありません。
それでもこのページにある理由。問題はアルゴリズムではなく 64 ビットブロックです:1 つの鍵の下で約 32 GiB を超えると、誕生日衝突がデータを漏らします(3DES と同じ限界、Sweet32 式)。Schneier 自身が新規には後継の Twofish(AES 最終候補)や AES を推奨しています。Blowfish は bcrypt の中で生きています — パスワードハッシュの鍵スケジュールこそ Blowfish です — これは問題ありません。ハッシュはギガバイトではなく小さな入力を使うからです。
古典ベクトル。全ゼロ鍵と全ゼロ平文は 4ef997456198dd78 に暗号化されます(サンプル出力の最初のブロック)。鍵「abcdefghijklmnopqrstuvwxyz」を「BLOWFISH」に適用すると 324ed0fef413a203。どちらも Schneier の公開ベクトルファイルから来ており、セルフテストがチェックします。
よくある間違い
- 新しいデータにこれらを使う。このページの暗号で非推奨でないのは Blowfish(ブロックサイズ制限あり)だけです。正しい現代の選択は AES-GCM — AES 暗号化 / 復号を参照。
- パスワードからの DES 鍵。8 文字のパスワードは 56 ランダムビットではありません。文字あたり数ビットのエントロピーです。古いシステムはまさにこれをやり、「DES で暗号化された」アーカイブが辞書攻撃で数分で落ちる最も一般的な理由です。
- CBC で IV を再利用する。すると最初のブロックが、同じ鍵の下でのメッセージ間の平文の等価性を漏らします。ランダム IV ボタンが存在する理由です。
- RC4 の鍵ストリームを再利用する。RC4 は同じ鍵に対して同じ鍵ストリームを XOR します:1 つの鍵で 2 つのメッセージを暗号化するのは 2 回目のワンタイムパッドであり — 暗文同士を XOR すると両方の平文が落ちてきます。WEP の致命的欠陥はまさに鍵ストリーム再利用の構造でした。
- 「復号できるから正しい」と仮定する。ここの ECB/CBC は復号時にパディングしか検証しません — 間違った鍵でも、パディングが外れるかもしれないゴミに剥がれるだけです。どのレガシーモードにも完全性チェックはありません。必要なら AES-GCM が必要で、これらではありません。
- 3DES を「168 ビット」と数える。生鍵は 168 ビットですが実効強度は 112 です — 中間者攻撃が 3 重暗号化を 2 重+αに減らします。3DES の祖先の構造に対して行ったのとまったく同じです。
よくある質問
なぜ破られた暗号のツールを保持するのですか?互換性のためです。暗号化されたバックアップ、書き出された旧形式ファイル、キャプチャされたプロトコルトレース、CTF の課題、アップグレードできないハードウェアは、今もこれらの暗号を話します。古いデータを読むのは正当です。新しいデータに書くのは正当ではありません。
DES 鍵に奇数パリティ / 非 ASCII バイトがあります。DES は各鍵バイトのパリティビットを無視するため、実効鍵は関係なく残りの 56 ビットです。このページは任意の 8 バイトを受け付け、偶数パリティを強制しません。
復号されたテキストがときどきゴミに見えるのはなぜ?鍵違い、モード違い、IV 違い、またはデータが想定と違う方法で暗号化されています。認証タグがないため、「鍵違い」のきれいなエラーは存在しません — パディングチェックが唯一の手がかりで、運良く通過することもあります(1/256 の確率)。
Blowfish は自分のファイルに安全ですか?小さなファイルには暗号学的にイエス(実用的な突破なし)。1 つの鍵の下でのギガバイト規模にはノー — 64 ビットブロックの誕生日限界は鍵強度ではなくデータ量の問題です。Twofish または AES がこの問題を避けます。
どこかで見た 72 バイトの Blowfish 鍵は?72 バイトまで受け付ける実装もありますが、Schneier のリファレンスは 56 を使い、それを超えるバイトは標準スケジュールで追加の拡散を与えません。このページはリファレンスに従います:4..56 バイト。