概要
コンピュータで情報を守るために整備された暗号理論と、DES(Data Encryption Standard)につながる共通鍵暗号について説明する。
共通鍵暗号は、暗号化と復号で同じ鍵を使う方式であり、大量データを高速に守るための基本になる。
1940年代後半から1970年代にかけて、シャノンの理論、Feistel構造、DESの標準化によって、現代的なブロック暗号の考え方が形になった。
この記事の構成
- 共通鍵暗号を支える理論
1940年代後半になると、暗号は経験的な技術だけではなく、数学的に分析される対象になった。 - 共通鍵暗号の基本
共通鍵暗号とは、暗号化と復号に同じ鍵を使う暗号方式。 - ブロック暗号とストリーム暗号
ブロック暗号は、平文を固定長のブロックに分け、ブロックごとに暗号化する方式。 - Feistel構造で理解するDES
Feistel構造は、平文ブロックを左右に分け、片方を関数に通してもう片方と組み合わせ、左右を入れ替える構造。 - DESから3DESへ
DESの鍵長不足を補うために3DESへ移行した流れと、その限界を整理。
共通鍵暗号を支える理論
- シャノンの暗号理論
1940年代後半になると、暗号は経験的な技術だけではなく、数学的に分析される対象になった。
特にクロード・シャノンは、暗号の安全性を情報理論の観点から整理した。
「暗号文を見ても平文について何も分からない」という理想的な安全性は、後に完全秘匿性として理解される。 - 完全秘匿性とワンタイムパッド
完全秘匿性を満たす代表例は、十分にランダムな鍵を平文と同じ長さだけ用意し、一度だけ使うワンタイムパッドとなる。
ただし、現実には平文と同じ長さの完全ランダムな鍵を安全に配布し、再利用しないように管理することが難しい。
そのため、実用暗号では「解読に現実的でない計算量が必要」という意味で安全性を考えるようになる。
共通鍵暗号の基本
- 同じ鍵を使う暗号方式
共通鍵暗号とは、暗号化と復号に同じ鍵を使う暗号方式となる。
送信者と受信者が同じ鍵を事前に共有しておき、送信者はその鍵で平文を暗号文へ変換。
受信者は同じ鍵を使って暗号文を平文へ戻す。\[ {\small C = E_{K}(P), \quad P = D_{K}(C) } \] - 鍵配布の問題
共通鍵暗号は高速で実用的だが、通信相手ごとに鍵を安全に渡す必要がある。
例えば、10人が全員と安全に通信したい場合、相手ごとに別の鍵を持つ必要がある。
2人の組合せごとに1本の鍵を用意すると、必要な鍵は次の \(45\) 本となる。\[ {\small \frac{10(10-1)}{2}=45 } \]一般に利用者が \(n\) 人なら鍵は \(\frac{n(n-1)}{2}\) 本必要となり、利用者が増えるほど、鍵の配布、保管、更新が難しくなる。
この課題は、後の公開鍵暗号が登場する大きな理由となった。
ブロック暗号とストリーム暗号
- ブロック暗号
ブロック暗号は、平文を固定長のブロックに分け、ブロックごとに暗号化する方式となる。
例えば、現在広く使われるAESでは、128ビットのブロックを基本単位として扱う。
ブロック暗号では、同じ鍵でも利用モードや初期値によって、同じ平文ブロックが同じ暗号文にならないように工夫する。 - ストリーム暗号
ストリーム暗号は、鍵から疑似乱数の列である鍵ストリームを作り、平文と逐次組み合わせる方式となる。
考え方はワンタイムパッドに近いが、完全ランダムな使い捨て鍵ではなく、鍵から生成した鍵ストリームを使う。
そのため、同じ鍵や同じ初期値を再利用しないことが非常に重要になる。 - ブロック暗号とストリーム暗号の比較
方式 処理単位 考え方 注意点 ブロック暗号 固定長のブロック 平文をかたまりに分けて変換。 利用モードや初期値の扱いが重要になる。 ストリーム暗号 ビット列やバイト列 鍵ストリームと平文を逐次組み合わせる。 同じ鍵ストリームを再利用しない。
Feistel構造で理解するDES
- Feistel構造
Feistel構造は、平文ブロックを左右に分け、片方を関数に通してもう片方と組み合わせ、左右を入れ替える構造となる。
平文ブロックとは、ブロック暗号が一度に処理する固定長の平文のかたまりを指す。
Feistel構造では、その平文ブロックを左半分 \(L_0\) と右半分 \(R_0\) に分けて処理を進める。この構造の重要な点は、暗号化と復号で同じような処理を使えることにある。
復号では、ラウンド鍵を逆順に使うことで元の平文へ戻せる。※ ラウンドは、暗号化の中で繰り返す1ステップのこと。
ラウンド鍵は、その1ステップごとに使う鍵であり、元の秘密鍵から \(K_1, K_2, K_3, \ldots\) のように展開して作られる。次の図は、Feistel構造の1ラウンドで値がどのように流れるかを表している。
1ラウンドだけを見ると、処理は次のように進む。
- 平文ブロックを左半分 \(L_0\) と右半分 \(R_0\) に分ける。
- 右半分 \(R_0\) とラウンド鍵 \(K_1\) を関数 \(F\) に入れる。
- 左半分 \(L_0\) と \(F(R_0, K_1)\) をXORする。
- 左右を入れ替え、次のラウンドへ進む。
次の値 作り方 \(L_1\) \(R_0\) \(R_1\) \(L_0 \oplus F(R_0, K_1)\) - DESの標準化
DESは、1970年代に標準化された代表的な共通鍵ブロック暗号となる。
DESは64ビットブロックを扱い、56ビットの鍵を使う。
当時は実用的な暗号標準として広く使われたが、計算機性能の向上によって、56ビット鍵は総当たり攻撃に耐えにくくなった。
DESから3DESへ
- DESの限界
DESの大きな弱点は、現在の計算能力に対して56ビットの鍵が短く、総当たり攻撃が現実的になったことにある。
さらに、64ビットという小さなブロック長は、同じ鍵で大量のデータを処理したときにブロックの衝突が起こりやすくなる問題にもつながる。コンピュータの性能が上がると、可能な鍵を順番に試す攻撃が現実味を持つ。
そのため、DESをそのまま使い続けることは難しくなった。 - 3DES
3DES は、DESを複数回適用することで安全性を高めようとした方式となる。
既存のDES実装との互換性を保ちながら安全性を延ばす目的があった。
しかし処理が重く、ブロックサイズも古いため、現在ではAESのような新しい標準へ移行するのが基本となる。
まとめ
- 完全秘匿性は理論的な理想であり、実用暗号では現実的な計算量で解読できないことを安全性の基準とする。
- 共通鍵暗号は同じ鍵を共有して高速に処理し、公開鍵暗号は公開鍵と秘密鍵を分けて鍵共有の問題へ対応。
- ブロック暗号は固定長のデータ単位、ストリーム暗号は鍵ストリームと逐次組み合わせて暗号化。
- Feistel構造とDESはブロック暗号の発展に大きな役割を持ったが、DESの鍵長不足から後のAES標準化へつながった。
- 暗号方式が強くても、鍵の配布、更新、保管などの運用が弱いと安全性は下がる。
参考文献
- CRYPTREC「CRYPTREC暗号の仕様書」(日本語・公的な暗号仕様一覧)
- Claude E. Shannon, Communication Theory of Secrecy Systems(英語・情報理論的暗号研究の原論文)
- National Institute of Standards and Technology, FIPS 46-3, Data Encryption Standard(DES、廃止済み)(英語・旧標準原文)
- National Institute of Standards and Technology, SP 800-67 Rev. 2, Triple Data Encryption Algorithm(TDEA、廃止済み)(英語・旧標準原文)
- National Institute of Standards and Technology, FIPS 197, Advanced Encryption Standard(AES)(英語・標準原文)