第 7 章 セキュリティと暗号化
7.1 セキュリティモデル
DTP 実装はエンドツーエンド暗号化を提供 しなければならない。セキュリティモデルは以下の不変条件を満たさ なければならない:
- 対象 iFay インスタンスのみが、受信した Payload を復号できなくては ならない。
- FayGer ランタイム環境はいかなる場合でも平文データにアクセス してはならない。
- 中間ネットワークノードは Payload の平文を読み取って はならない。
- DTP 実装は暗号化鍵を自ら管理 してはならない。
7.2 暗号化範囲
暗号化範囲は LogicalFrame の Payload に厳密に限定 しなければならない。
7.2.1 暗号化しなければならない内容
以下のデータは暗号化 しなければならない:
- LogicalFrame の
payloadフィールド(つまり Fragment のdataフィールド、および(Frame として搬送される場合の)RequestFrame、ResponseFrame、ControlFrame の内容)。
7.2.2 暗号化してはならない内容
以下のデータは暗号化 してはならず、平文で伝送 しなければならない:
- LogicalFrame の
header(protocolVersion、frameType、fragmentId、agreementId、originTimestamp、dagDependencies、encryptionMetadata、sequenceNumberを含む)。
暗号化メタデータ自体は暗号化 してはならない。これは受信側が復号前に復号パラメータを判定できるようにするためである。
7.3 鍵管理
7.3.1 鍵の出所
DTP 実装は CAP で事前ネゴシエーションされた鍵を使用 しなければならない。具体的な要件:
- CAP は接続確立段階で身元検証と鍵交換を完了 しなければならない。
- DTP 実装は CAP が提供する
sessionKeyを使用して Payload の暗号化/復号を行わ なければならない。 - DTP 実装は暗号化鍵を自ら生成、ネゴシエーション、または交換 してはならない。
7.3.2 CAPContext インタフェース
DTP 実装は以下のインタフェースを介して CAP が提供するコンテキストを受け取ら なければならない:
interface CAPContext {
identity: string;
sessionKey: Uint8Array;
verified: boolean;
}
| フィールド | 規範的要件 |
|---|---|
identity | 対端の身元識別子で なければならない |
sessionKey | CAP がネゴシエーションしたセッション鍵のバイト列で なければならない |
verified | CAP の検証状態を反映 しなければならない |
7.3.3 CAP 前提条件
DTP 実装はデータ伝送を開始する前に CAPContext を検証 しなければならない:
verified === falseの場合、いかなるデータフレームの送信も拒否し、KEY_NOT_READYエラー(2002)を返 さなければならない。sessionKeyが空または長さが無効である場合、KEY_NOT_READYエラーを返 さなければならない。- ネゴシエーションフレーム(Request_Frame、Response_Frame)の伝送 も この前提条件の制約を受ける。
7.4 暗号化メタデータ
各 LogicalFrame のフレームヘッダーは EncryptionMetadata を携帯 しなければならない:
interface EncryptionMetadata {
algorithm: string;
keyVersion: number;
}
7.4.1 アルゴリズム識別子
algorithm フィールドは暗号化アルゴリズムの識別文字列で なければならない。以下の標準化された命名のいずれかを使用 すべきである:
| 識別子 | アルゴリズム | ステータス |
|---|---|---|
"AES-256-GCM" | AES-256 in Galois/Counter Mode | 推奨 |
"ChaCha20-Poly1305" | ChaCha20 with Poly1305 | 推奨 |
"AES-128-GCM" | AES-128 in Galois/Counter Mode | 使用 してもよい |
実装は少なくとも AES-256-GCM と ChaCha20-Poly1305 のいずれかをサポート しなければならない。相互運用性を高めるために両方をサポートすることが 推奨される。
実装は以下を使用 してはならない:
- ECB モード(安全でない)
- 認証なしの暗号化モード(MAC を伴わない CBC、CTR)
- 既知の弱点を持つアルゴリズム(DES、3DES、RC4)
7.4.2 鍵バージョン番号
keyVersion は鍵ローテーションをサポートするための非負整数で なければならない:
- CAP が鍵ローテーションをトリガする場合、新しい鍵の
keyVersionは前のバージョンより厳密に大きく なければならない。 - 受信側は
keyVersionを使用して対応する復号鍵を選択 しなければならない。 - 実装は飛行中(in-flight)の Fragment をサポートするために、少なくとも 1 つの旧鍵バージョンを維持 すべきである。
7.5 暗号化のラウンドトリップ整合性
実装は以下の暗号化ラウンドトリップ整合性プロパティを満たさ なければならない:
- 正しい鍵(送信側が使用した鍵と一致する)で暗号化した後に復号すると、元の Payload とバイト単位で同じ出力を生成 しなければならない。
- 誤った鍵で復号すると失敗 しなければならず、
DECRYPTION_FAILEDエラー(2001)を返 さなければならない。 - 復号失敗時、実装は部分復号結果や破損したデータを返 してはならない。
7.6 端末側の復号
端末が受信側となる場合(データ注入のシナリオ):
- DTP_Slave は端末が CAP 接続確立段階で提出した鍵を使用して復号 しなければならない。
- その鍵は端末が CAP で提出した秘密鍵/セッション鍵に対応 しなければならない。
- 端末は他のいかなる鍵での復号結果も受け入れ てはならない。
7.7 復号失敗の処理
実装は以下の規則に従って復号失敗を処理 しなければならない:
- 単一の復号失敗:フレームを破棄し、
DECRYPTION_FAILEDエラー通知(2001)を送信する。 - 連続する復号失敗が閾値を超えた場合(実装定義、推奨 値は 3 回): a. CAP の鍵再交換をトリガ すべきである。 b. 上位アプリケーションにセキュリティ異常を通知 すべきである。
- 実装は複数回の復号失敗の後、同一フレームを無限に再試行 してはならない。
7.8 セキュリティ脅威への防護
実装はプロトコル設計を通じて以下の脅威に対して防護 しなければならない:
| 脅威 | 防護機構 |
|---|---|
| 中間者の盗聴 | Payload のエンドツーエンド暗号化 |
| FayGer の覗き見 | Payload 暗号化、FayGer は暗号文のみ可視 |
| 鍵漏洩 | 鍵バージョン番号機構による鍵ローテーションのサポート |
| 身元なりすまし | CAP に検証を委任 |
| リプレイ攻撃 | シーケンス番号の単調増加 + セッションバインド |
| フレーム改ざん | 認証付き暗号(AEAD)アルゴリズムを使用 |
7.9 リプレイ防護
実装は以下の機構を介してリプレイ攻撃に対して防護 しなければならない:
- シーケンス番号の単調増加:受信側は確認済みの最高シーケンス番号以下のシーケンス番号を持つフレームを拒否 しなければならない(再開シナリオを除く)。
- セッションバインド:シーケンス番号空間は具体的なセッションにバインド しなければならない。新しいセッションはシーケンス番号をリセット しなければならない。
- AEAD 認証:暗号化アルゴリズムはメッセージ認証(GCM、Poly1305 など)を提供 しなければならない。
7.10 メタデータのプライバシー
実装は以下に注意 すべきである:フレームヘッダー内の平文メタデータは以下の情報を漏洩する 可能性がある:
- 通信対端の身元(
agreementIdの関連付けを介して) - 通信時間パターン(
originTimestampとsequenceNumberを介して) - データ伝送頻度(フレーム間の時間差を介して)
実装は以下の方法でメタデータのプライバシーを強化 してもよい:
- トラフィックパディングを有効にする(実装定義)。
- 難読化された伝送層を使用する(TLS 1.3 ベースの ECH など)。
ただし本仕様は実装にメタデータプライバシー保護の提供を 要求しない。
