高度な暗号化の概念:CSPRNG から前方秘匿性まで
データ漏洩が蔓延し、高度な国家主導の監視が行われる現代において、暗号化の役割はニッチな学問分野からデジタル経済の基盤へと変化しました。多くの開発者は「ハッシュ」や「共通鍵暗号」といった基本的な概念には馴染みがありますが、システムの現実世界でのセキュリティは、より高度で微妙なプリミティブに依存することがよくあります。
このガイドでは、TLS 1.3 や Signal といった現代の暗号プロトコルを可能にする重要な構成要素を探ります。乱数の生成から、今日の秘密が将来鍵が侵害されたとしても安全であり続けるという保証までを解説します。
1. 乱数の基礎:CSPRNG
すべての暗号操作は秘密から始まり、すべての秘密は乱数から始まります。しかし、根本的に決定論的なマシンであるコンピュータの世界では、真の乱数を見つけるのは驚くほど困難です。
CSPRNG とは?
暗号論的擬似乱数生成器 (CSPRNG) は、真のランダムノイズと区別がつかない数列を生成するように設計された特殊なアルゴリズムです。標準的な PRNG(JavaScript の Math.random() など)とは異なり、CSPRNG は 2 つの重要な要件を満たす必要があります。
- 次ビットテスト: 数列の最初の k ビットが与えられたとき、無限の計算能力を持つ攻撃者であっても、$(k+1)$ 番目のビットを 50% を超える確率で予測できてはなりません。
- 状態侵害時の耐性: 生成器の内部状態が侵害された場合、過去のランダム出力を復元すること(バックトラッキング耐性)や、将来の出力を予測すること(予測耐性、新しいエントロピーが追加されることが前提)が不可能である必要があります。
エントロピーソース
CSPRNG の性能は、そのエントロピーソースに依存します。現代のオペレーティングシステムは、キーボードのタイミング、マウスの動き、ディスク I/O 割り込み、熱ノイズなどのハードウェアイベントから「ノイズ」を収集し、生成器のシードにします。Linux では、これは /dev/urandom によって処理されます。
2. 認証付き暗号 (AEAD)
何十年もの間、開発者は機密性のために暗号化し、完全性のために MAC(HMAC など)を使用するように教えられてきました。この「暗号化してから MAC (Encrypt-then-MAC)」というアプローチは安全ですが、実装ミスが発生しやすいという欠点があります。
AEAD の台頭
AEAD (Authenticated Encryption with Associated Data) は、単一の暗号プリミティブで機密性と完全性の両方を提供することで、これを簡素化します。AES-GCM や ChaCha20-Poly1305 といった AEAD モードを使用すると、アルゴリズムは以下を生成します。
- 暗号文: 暗号化されたデータ。
- 認証タグ: 暗号文が改ざんされていないことを証明する暗号チェックサム。
関連データ (AD)
「AD」部分は、暗号化されていないデータを認証することを可能にします。例えば、ネットワークパケットにおいて、ヘッダー(送信先 IP を含む)はルーターが読み取れるように平文のままである必要がありますが、攻撃者が検出されずに送信先を変更できないように認証されるべきです。
3. 鍵派生関数 (KDF)
生のパスワードを暗号化鍵として使用してはなりません。人間は予測可能なパスワードを選びますが、暗号アルゴリズムは高エントロピーで均一に分布したビット列を必要とするからです。
KDF の役割は?
鍵派生関数 (KDF) は、エントロピーソース(パスワードや鍵交換からの共有秘密など)を受け取り、そこから 1 つ以上の暗号的に強力な鍵を「伸長」または「派生」させます。
現代の KDF 標準
- PBKDF2: 総当たり攻撃を遅らせるために、ハッシュ化を繰り返す古い標準です。
- Argon2: パスワードハッシュコンペティション (PHC) の優勝者であり、GPU や ASIC ベースの解析に耐性を持つように設計されています。
- HKDF (HMAC-based KDF): TLS 1.3 などのプロトコルで広く使用されており、単一の共有秘密から複数の独立した鍵(暗号化鍵と認証鍵など)を派生させます。
4. エフェメラル鍵交換と前方秘匿性
現代の暗号化における最も強力な概念の一つが、完全前方秘匿性 (PFS) です。
静的鍵の問題
古いバージョンの SSL では、サーバーは静的な RSA 秘密鍵を使用してセッション鍵を交換していました。攻撃者が何年分もの暗号化されたトラフィックを記録し、後にサーバーの秘密鍵を盗み出すことに成功した場合、収集した過去のトラフィックをすべて復号できてしまいます。
解決策:エフェメラル鍵交換
現代のプロトコルは、エフェメラル Diffie-Hellman (DHE) または 楕円曲線 Diffie-Hellman (ECDHE) を使用します。
- エフェメラル (Ephemeral) とは、鍵が一時的であることを意味します。セッションごとに新しい、一意の鍵ペアが生成されます。
- セッションが終了すると、鍵はメモリから削除されます。
前方秘匿性の達成
サーバーの長期的な身元確認鍵は、セッション鍵を暗号化するためではなく、交換に署名する(サーバーの身元を証明する)ためにのみ使用されるため、長期鍵が侵害されても、攻撃者が過去のトラフィックを復号する助けにはなりません。これがプライバシーのゴールドスタンダードです。
5. まとめ:安全なシステムの構築
現代的で安全なアプリケーションを構築するには、以下のアーキテクチャパターンに従う必要があります。
- システムが提供する CSPRNG を使用して秘密を生成する(例:ブラウザの
crypto.getRandomValues()や Node.js のcrypto.randomBytes())。 - Argon2 または Scrypt を使用してパスワードを保存する。
- AES-256-GCM などの AEAD モードを使用して、保存データを保護する。
- 前方秘匿性のために、ECDHE を備えた TLS 1.3 を使用して通信データを保護する。
- 異なる目的で同じマスター鍵を再利用するのではなく、HKDF を使用してサブ鍵を派生させる。
これらの高度な概念を理解することで、単にセキュリティの「項目をチェックする」段階を超え、現在の脅威と将来の脆弱性の両方に対して弾力性のあるシステムを構築し始めることができます。