本記事はGeminiの出力をプロンプト工学で整理した業務ドラフト(未検証)です。
Internet-Draft: Heavily Modified Trivial File Transfer Protocol (HMTFTP) — AEAD暗号化によるセキュアな軽量ファイル転送
【背景と設計目標】
IoTデバイス向けに、DTLS等の高負荷なスタックを排除し、TFTPにAEAD暗号を直接統合した軽量・安全な転送プロトコル。
従来のRFC 1350 (TFTP) は暗号化や改ざん検知機能を持たず、セキュアなファイル転送(ファームウェア更新など)にはDTLS(Datagram Transport Layer Security)を組み合わせるのが一般的でした。しかし、リソースの極めて厳しいIoTデバイスにおいて、DTLSスタックの実装フットプリントとメモリ消費は大きな障壁となります。
HMTFTPは、TFTPの「シンプルさ」を継承しつつ、プロトコル自体に軽量な鍵交換機構とAEAD(Authenticated Encryption with Associated Data)による暗号化を直接組み込むことで、極小のフットプリントでセキュアな転送を実現する新規設計のプロトコルです。旧規格(RFC 1350)との直接的な後方互換性はありませんが、UDPポートを分ける、または特定のオプトインハンドシェイクを行うことで、既存ネットワークとの共存を図ります。
【通信シーケンスと動作】
HMTFTPは、データ転送を開始する前に、クライアントとサーバ間で1往復(1-RTT)の鍵交換ハンドシェイクを行い、共通鍵(セッション鍵)を生成します。
sequenceDiagram
autonumber
participant "Client as HMTFTP Client"
participant "Server as HMTFTP Server"
Note over Client, Server: 【1. ハンドシェイク / 鍵交換 (1-RTT)】
Client ->> Server: SEC_REQ (Client Key Share: ECDH Public Key, Cipher Suites)
Server -->> Client: SEC_RES (Server Key Share, Selected Cipher Suite, Salt)
Note over Client, Server: 互いにセッション鍵 (AEAD Key) を導出
Note over Client, Server: 【2. セキュアデータ転送 (暗号化 & 認証)】
Client ->> Server: SWRQ (Secure Write Request / Session ID, Encrypted Filename)
Server -->> Client: SACK (Secure Ack 0)
Client ->> Server: SDATA (Secure Data Block 1 / AEAD Encrypted Payload + Tag)
Server -->> Client: SACK (Secure Ack 1)
Note over Client, Server: 【3. 接続クローズ】
Client ->> Server: SDATA (Secure Data Block N [EOF] / Encrypted Empty Payload)
Server -->> Client: SACK (Secure Ack N)
動作解説
鍵交換(ステップ1-2):クライアントは
SEC_REQ(Security Request)を送信し、楕円曲線ディフィー・ヘルマン(ECDH)の公開鍵情報を提示します。サーバはSEC_RESで応答し、鍵合意(Key Agreement)を完了します。要求(ステップ3-4):合意された共有鍵から導出されたセッション鍵を用い、ファイル名などのメタデータをAEADで暗号化した
SWRQ(Secure Write Request) を送信します。データ転送(ステップ5-6):データ本体は固定長(または動的調整)のブロックに分割され、ブロックごとにNonce(ワンタイムトークン)を更新しながら暗号化されて送信されます。
【データ構造 / パケットフォーマット】
HMTFTPの核となる SDATA (Secure Data) パケットの構造は、不要なオーバーヘッドを徹底的に排除したレイアウトとなっています。
0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Opcode (2B) | Session ID (2B) | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Block Number (4B) | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | | + Nonce / IV (12B) + | | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | | . Encrypted Payload (Variable Length...) . . . +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | | + Auth Tag (16B) + | | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
フィールド詳細解説
Opcode (16-bit, Offset 0:16): パケットタイプを定義(例:
0x0006= SDATA,0x0007= SACK)。Session ID (16-bit, Offset 16:16): ハンドシェイク時に割り当てられる一意の識別子。ポート番号の変更やNAT越え時の一貫性維持に使用。
Block Number (32-bit, Offset 32:32): 送信ブロックのシーケンス番号。RFC 1350の16-bit制限を拡張し、大容量ファイルにも対応。
Nonce / IV (96-bit, Offset 64:96): AEAD暗号(ChaCha20-Poly1305等)に必須の一意な値。Block NumberとSession IDから決定論的に生成、または明示的に送信。
Encrypted Payload (可変長): 暗号化されたファイルデータ本体。
Auth Tag (128-bit, Offset 末尾16B): AEADによって生成されるメッセージ認証符号。データ改ざんおよび送信元の真正性を保証。
【技術的な特徴と比較】
| 評価項目 | TFTP (RFC 1350) | CoAP over DTLS (RFC 9147) | HMTFTP (Draft) |
|---|---|---|---|
| トランスポート | UDP (ポート 69) | UDP (ポート 5684) | UDP (任意 / 新規割当) |
| 暗号化方式 | なし | DTLS 1.3 (AES-GCM / CCMP) | AEAD (ChaCha20-Poly1305 内蔵) |
| 鍵交換 RTT | なし (暗号化なし) | 1 ~ 2 RTT (フルハンドシェイク) | 1 RTT (ECDH搭載) |
| フットプリント | 極小 (< 10KB) | 大 (DTLS/CoAPスタック: 100KB+) | 中 (暗号ライブラリ依存: ~30KB) |
| HOL Blocking | あり (Stop-and-Wait) | あり (仕様による) | あり (ただし実装依存で拡張可能) |
| MTU 考慮 | パケット断片化のリスク | パケット断片化のリスク | MTU制限内の自動セグメンテーション |
技術キーワード解説
HOL Blocking (ヘッドオブラインブロッキング): HMTFTPはシンプルな「Stop-and-Wait」方式を踏襲しているため、前パケットのACKを受信するまで次パケットを送信しません。このため、パケットロスによる待ち(HOL Blocking)が発生しますが、これはIoTの低帯域環境下でのバッファ溢れを防ぐトレードオフです。
0-RTT: ハンドシェイク時に前回のSession IDを再利用(レジューム)することで、2回目以降の接続では1往復の遅延すらなく暗号化通信を開始できます。
多重化 (Multiplexing): Session IDをパケットヘッダーに配置しているため、同一のUDPポート上で複数の暗号化セッションを安全に識別・多重化できます。
【セキュリティ考慮事項】
1. リプレイ攻撃(Replay Attack)への耐性
各パケットには単調増加する32-bitの Block Number が含まれており、これがAEADのNonce(初期化ベクトル)生成の入力として利用されます。攻撃者がキャプチャした過去の有効なパケットを再送信しても、受信側は期待するBlock Number以外のパケットや、Nonceが重複したパケットを破棄するため、リプレイ攻撃は完全に無効化されます。
2. ダウングレード攻撃(Downgrade Attack)への耐性
HMTFTPは設計上、非暗号化のTFTPとは完全に独立したOpcodeとハンドシェイクフェーズを持っています。最初の SEC_REQ の時点で「暗号化必須(Secure-Only)」のネゴシエーションが行われるため、攻撃者が経路間でパケットを書き換えて平文通信(RFC 1350)に強制的にフォールバックさせることはできません。
3. 前方秘匿性(PFS: Perfect Forward Secrecy)
鍵交換フェーズにおいて、静的なマスターキーではなく、セッションごとに使い捨てるエフェメラル鍵(ECDHE: Ephemeral Elliptic Curve Diffie-Hellman)を採用しています。万が一、将来的にサーバの固定秘密鍵が漏洩した場合であっても、過去に記録された通信トラフィックを遡って解読されるリスクを排除(PFSを確保)しています。
【まとめと実装への影響】
開発者およびネットワークエンジニアがHMTFTPを導入・実装するにあたり、留意すべきポイントは以下の3点に集約されます。
暗号アクセラレータの活用 HMTFTPはChaCha20-Poly1305を推奨暗号ハードウェアとして想定しています。IoTチップ(Cortex-M系列など)に搭載されているハードウェア暗号化エンジン(AES-GCM等)を利用可能な場合は、暗号スイートの選択肢を適切に制限し、CPU負荷と消費電力を最小限に抑える実装設計が必要です。
MTUサイズとパケット分割の設計 AEAD暗号化を適用すると、パケットには「Session ID」「Nonce」「Auth Tag(16バイト)」が追加され、実効ペイロードが減少します。UDPの断片化(IP Fragmentation)によるパケット消失を防ぐため、物理ネットワークのMTU(一般的には1500バイト、無線環境ではより小さく設定)から逆算した最大ペイロードサイズ(通常512〜1024バイト程度)の厳密な設計が求められます。
Session IDの管理とタイムアウトポリシー ステートレスなTFTPとは異なり、HMTFTPのサーバは「Session ID」と「共有鍵」のペアをメモリ上に一時保持(ステートフル)する必要があります。リソース制限下でのDoS攻撃(セッションリソース枯渇攻撃)を防ぐため、積極的なセッションタイムアウトの適用と、不活性接続のクリーンアップアルゴリズムの実装が必須です。

