Noiseプロトコルフレームワーク
WireGuard、WhatsApp、Lightningで使われる、独自の暗号ハンドシェイクを構築するためのNoiseを学びます。
「Noiseプロトコルフレームワーク」はCoddyKit上の無料Cryptology Academyレッスンです。 これはレッスン3/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはCryptology Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Cryptology Academyコースには全4レッスンが含まれています。
Noise Frameworkとは
Noise Protocol Framework(Trevor Perrin、2016年。現行改訂版は2018年)は、少数のプリミティブとパターン言語を使ってセキュアチャネルプロトコルを構築するためのフレームワークです。Noiseは単一のプロトコルを規定するのではなく、DH操作の実行順序を記述するハンドシェイクパターンの語彙を定義します。Noiseの有効なパターンはすべて、具体的なDH関数(Curve25519またはCurve448)、暗号関数(AESGCMまたはChaChaPoly)、ハッシュ関数(SHA-256、SHA-512、BLAKE2)を使ってインスタンス化できます。NoiseはWireGuard、WhatsApp、Signal(X3DHの基盤として)、Lightning Network、I2Pで使われています。
Noiseの役割と鍵
Noiseのすべてのハンドシェイクには、イニシエーター(I)とレスポンダー(R)が存在します。各当事者は、2種類の鍵を持つことができます。静的鍵(長期的な身元鍵。s/Sで表記)と、エフェメラル鍵(セッションごとに新しく生成される鍵。e/Eで表記)です。小文字はローカル側の鍵を、大文字はリモート側の公開鍵を表します。Noiseパターンは、どの鍵を送信するか(平文または暗号化した状態)と、どのDH操作を実行するかを指定します。たとえば、「e」は「自分のエフェメラル公開鍵を送信する」を、「es」は「DH(my_ephemeral, remote_static)を実行する」を意味します。各DHの出力は、ハンドシェイクの進行中のハッシュ状態に混ぜ込まれます。
Noiseの対称状態
Noiseの中核はSymmetricStateであり、3つの値を管理します。ck(chaining key。プロトコル名のハッシュで初期化)、h(handshake hash。進行中のトランスクリプトハッシュ)、k(現在の暗号化鍵)です。MixKey(input)はHKDF(ck, input)を実行してckとkを更新します。MixHash(data)はdataをhにハッシュします。EncryptAndHash(plaintext)はkで暗号化し、暗号文をhに混ぜ込みます。DecryptAndHash(ciphertext)は復号して、暗号文をhに混ぜ込みます。ハンドシェイクハッシュhはトランスクリプトへのバインディングを提供するため、攻撃者がどのメッセージを変更してもhが変化し、復号に失敗します。ハンドシェイクの最後に、Split()は送信用と受信用に分離された2つのCipherStateを生成します。
Noise_XXパターン
Noise_XXは、最も一般的に使われる相互認証パターンです。ハンドシェイク中に両者の静的鍵を送信することで、相互の静的鍵認証を実現します。パターンは次のとおりです。(1) -> e(イニシエーターがエフェメラル公開鍵を送信)。(2) <- e, ee, s, es(レスポンダーがエフェメラル鍵を送信し、DH(e,e)とDH(e,s_resp)を実行して、暗号化した静的鍵を送信)。(3) -> s, se(イニシエーターが暗号化した静的鍵を送信し、DH(s_init, e_resp)を実行)。ステップ3の後、両者は3つのDH出力をセッション鍵に混ぜ込んでいます。ee(前方秘匿性)、es(サーバー認証)、se(クライアント認証)です。セッション終了後に長期鍵が漏えいしても、セッション鍵はその影響を受けません。
Noise_IKパターン(WireGuard)
WireGuardは、イニシエーターがレスポンダーの静的鍵を事前に知っているNoise_IKから派生したパターンを使います。(1) -> e, es, s, ss(イニシエーターがエフェメラル鍵を送信し、DH(e, S_resp)、暗号化した静的鍵の送信、DH(s_init, S_resp)を実行)。(2) <- e, ee, se(レスポンダーがエフェメラル鍵を送信し、DH(e_resp, e_init)とDH(e_resp, S_init)を実行)。IKパターンは、イニシエーターの身元秘匿(ステップ1で静的鍵をレスポンダーの静的鍵で暗号化)と、1 RTTでの完了を実現します。WireGuardは、リプレイを防ぐため、暗号化されたイニシエーターのペイロード内にタイムスタンプを追加します。これにより、WireGuardは2つのUDPパケットで完全なVPNハンドシェイクを完了できるという、特徴的なシンプルさを実現しています。
Noiseのハンドシェイクハッシュとチャネルバインディング
Noiseのハンドシェイク終了時のハンドシェイクハッシュhは、送信されたすべてのメッセージを対象とするトランスクリプトハッシュです。これはチャネルバインディング値として機能します。両者が同じhを計算できるため、Noiseセッションにバインドしたい第三者プロトコルは、hをnonceまたはチャネルIDとして含めることができます。これにより複合認証が可能になります。たとえば、TLS方式の証明書認証ステップをNoiseハンドシェイクの後に実行し、hを使って証明書をこの特定のセッションにバインドできます。チャネルバインディングは、あるセッションの認証資格情報を別のセッションにリプレイする、資格情報転送攻撃を防ぎます。Split()はセッション鍵とともにhをアプリケーションへ渡します。
Noiseの遅延パターンとフォールバック
Noiseは、イニシエーターがレスポンダーの静的鍵を事前に知らない状況に対応するため、遅延パターンをサポートしています。Noise_NX(イニシエーターは静的鍵を持たず、レスポンダーが静的鍵を送信)は、一方向TLSに相当します。Noise_XXは、両者が鍵を交換する必要がある場合に対応します。イニシエーターが推測したレスポンダーの静的鍵が正しくない場合(鍵ローテーション後など)、Noise_IKはNoise_XXfallbackへフォールバックできます。フォールバックパターンにより、レスポンダーは「間違った鍵を使っています。これが新しい公開鍵です」と通知できます。その際、外部の観測者にはフォールバックが発生したことを明らかにせず、プロトコルの不透明性を維持できます。
WhatsAppとSignalにおけるNoise
WhatsAppとSignalは、クライアントとサーバー間のセキュアチャネル確立にNoise_XXを使います。WhatsAppのバイナリプロトコルは、Curve25519、ChaChaPoly、SHA-256を使うNoise_XXを採用しています。クライアントの静的鍵は、長期的な身元鍵です。Noiseハンドシェイクの後、アプリケーション層で追加の認証(Signalへの登録、電話番号の検証)を実行します。SignalのX3DH(Extended Triple Diffie-Hellman)鍵合意は、非同期メッセージ交換を通じて2人のユーザー間に共有秘密を確立するために4回のDH操作を実行します。これは標準的なNoiseパターンではありませんが、同様のDH混合の概念を使います。その後、継続的なメッセージ暗号化はDouble Ratchetに引き継がれます。
NoiseとTLSの比較
NoiseとTLS 1.3は、異なる思想で同じ問題(認証付き鍵交換)に対処します。TLS 1.3は、規定された暗号スイート、証明書形式(X.509)、拡張機能を備えた単一のプロトコルです。ウェブブラウザーとサーバー向けに設計された、多くの用途に対応する標準プロトコルです。Noiseはフレームワークであり、証明書形式、PKI、トランスポートへのバインディングを一切規定しません。そのためNoiseは、より小規模で(WireGuardのNoise実装全体は400行未満です)、形式的に推論しやすい一方、アプリケーション側で身元管理を別途処理する必要があります。Noiseは、PKIが過剰となるクローズドシステム(アプリケーションとサーバー間、VPN)で好まれます。一方、証明書の相互運用性が必要なオープンシステム(ウェブ)ではTLSが使われます。
Noiseの形式的なセキュリティ
Noiseパターンは、eCK(extended Canetti-Krawczyk)セキュリティモデルで形式的に解析されています。Kobeissi、Bhargavan、BlanchetはProverifを使ってNoiseを解析し、12個すべての基本Noiseパターンについて、認証と鍵の機密性の証明を見いだしました。これらの証明は、標準的なDHの困難性仮定(Curve25519)と、基盤となるAEADおよびハッシュ関数の安全性を前提としています。Noiseは各DHを段階的に混ぜ込む構成になっているため、多数の状態遷移を持つ複雑なTLS類似プロトコルより推論しやすくなっています。Noiseの暗号学的検証により、WireGuardとWhatsAppは展開前からプロトコルの安全性に高い確信を得ることができました。
Noiseを正しく実装する
Noiseの実装でよくある落とし穴は次のとおりです。(1) パターンの混同:レスポンダーの静的鍵が確実に事前配布されていない状況でNoise_IKを使うと、身元の不一致につながります(イニシエーターが誤った鍵に気付かないまま暗号化する可能性があります)。(2) リプレイ保護:Noiseは認証を提供しますが、Transportフェーズのメッセージに対するリプレイ保護は提供しません。ノンス(64ビットカウンター)を必ず適用し、ラップアラウンド(2^64個のメッセージ送信後)が発生したら再鍵交換を行う必要があります。(3) プロローグの完全性:Noiseのプロローグ(ハンドシェイク開始前にhへ混ぜ込むバイト列)には、ダウングレード攻撃を防ぐため、プロトコルのコンテキスト(バージョン、アルゴリズムの選択)をすべて含める必要があります。(4) PSKの誤用:Noiseは事前共有鍵を混ぜ込むPSK拡張をサポートしますが、PSKにはユーザーパスワードではなく、高エントロピーの値を使う必要があります。
Noise Frameworkクイズ
ハンドシェイクパターンにおけるNoiseの表記「es」は何を意味しますか。
Noise Frameworkの復習
Noiseは、DH操作のパターン言語を使って認証付き鍵交換プロトコルを構築するためのフレームワークです。SymmetricStateはchaining key(ck)、トランスクリプトハッシュ(h)、暗号鍵(k)を管理し、MixKey/MixHashによって更新します。Noise_XXは1.5 RTTで相互認証を実現し、Noise_IK(WireGuard)はレスポンダーの鍵が既知であれば1 RTTで完了します。ハンドシェイクハッシュhはチャネルバインディングとして機能します。Noiseは、Proverifによってすべてのコアパターンについて形式検証されています。PKIが不要なクローズドシステムのプロトコル(WireGuard、WhatsApp)では、TLSよりNoiseが好まれます。正しい実装には、リプレイ保護、プロローグの完全性、高エントロピーのPSKが必要です。
よくある質問
「Noiseプロトコルフレームワーク」レッスンは無料ですか?
はい。「Noiseプロトコルフレームワーク」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Cryptology Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Cryptology Academyコースには全4レッスンが含まれています。
「Noiseプロトコルフレームワーク」で何を学びますか?
WireGuard、WhatsApp、Lightningで使われる、独自の暗号ハンドシェイクを構築するためのNoiseを学びます。 ブラウザで直接実行するハンズオンコードでCryptology Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
Cryptology Academyを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのCryptology Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン3/4です。
「Noiseプロトコルフレームワーク」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このCryptology Academyレッスンでコードを書いて実行できますか?
はい。すべてのCryptology Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。
このコースのすべてのレッスン
- Needham-Schroederプロトコルと攻撃
- Station-to-Stationプロトコル(STS)
- Noiseプロトコルフレームワーク
- 安全なプロトコル設計の原則