要約

  • Content-Digest はメッセージの実コンテンツを、Repr-Digest は選択された表現データ全体を照合する。一致しても、そのバイト列を選んだ人物は特定されない。
  • 判断に耐える記録では、対象バイト、アルゴリズム方針、再計算、署名範囲、鍵の権限、時刻、再送、業務検査、最終処理を別々に扱う。

正しい計算が、誤った許可に化けた

再計算した値は、送られてきた値と確かに同じだった。しかし、そこから「この設定を実行してよい」とは導けない。確認できたのは二つの値の関係であり、送信者の身元でも、操作の権限でもない。

本文とダイジェストを同じ者が自由に選べるなら、強力な SHA-256 も入場審査にはならない。攻撃者は自作の本文を普通にハッシュすればよい。受信側が同じ演算をすれば一致するのは当然である。

だから verified=true という表示は危うい。content_digest_matchedsignature_verifiedkey_authorized のように、何が成立したかを名詞付きで記録すべきだ。省かれた名詞の分だけ、証拠は過大評価される。

どのバイトを守るのか

RFC 9530 は旧来の Digest を二つに分けた。Content-Digest は HTTP メッセージが実際に運ぶコンテンツを対象にする。Repr-Digest は選択された表現データの全体を対象にする。

圧縮、範囲応答、メソッド、表現メタデータによって両者は異なり得る。ゲートウェイは圧縮済みの内容を照合し、アプリケーションは解凍後の表現が検証されたと思い込むかもしれない。両者とも局所的には正しく、守った対象だけが違う。

したがってアルゴリズム選択より先に、不変条件を決めなければならない。符号化前か後か、部分データか再構成後か。RFC 3230 が廃止された背景にも、「instance」が内容と表現の間で不統一に解釈された問題がある。

辞書を読めても信頼は生まれない

二つの欄は Structured Fields の辞書であり、キーがアルゴリズム、値がダイジェストのバイト列を示す。移行のため複数アルゴリズムを載せることもできる。

構文解析の成功は採用判断ではない。受信者は許可するアルゴリズム、複数値の扱い、失敗時の挙動を定める必要がある。IANA の登録簿は状態を示し、RFC 9530 は多くの用途で Active を推奨し、敵対的状況で Deprecated を使うことを禁じている。

Base64 はバイトの表現方式にすぎない。ハッシュ、符号化、署名は別の操作だ。また Want-Content-DigestWant-Repr-Digest は希望を伝えるヒントであり、相手は無視できる。必須要件はアプリケーション側の規則として明示しなければならない。

署名しても再計算は残る

HTTP Message Signatures は Content-Digest、メソッド、対象など、選択した要素を署名範囲にできる。これにより、宣言されたダイジェスト値を検証済みの鍵に結び付けられる。

ただし、署名は暗黙にメッセージ全体を覆わない。Content-Digest が署名入力に含まれなければ、署名成功はその欄について何も語らない。含まれていても、受信した本文を別途ハッシュし、値と比較する必要がある。

たとえば本文だけが置換され、署名済みのダイジェスト欄が残った場合、欄が変わらないので署名は有効なままになり得る。本文との不一致を見つけるのは独立した再計算である。

逆に、再計算だけで署名を検証しなければ、匿名の相手が一致する本文と値を渡せる。署名が本物でも、鍵がその操作を許可されているか、必要な要素を覆うか、有効時刻内か、再送でないかをアプリケーションが判断しなければならない。

トレーラーは確定時刻を後ろへ動かす

RFC 9530 は欄をヘッダーにもトレーラーにも置ける。送信完了まで値を計算できないストリームではトレーラーが便利だが、受信側が判断できるのも最後になる。

本文を読みながら状態を確定し、最後にトレーラーを見る設計では、失敗が不可逆な処理の後に判明する。検査完了までは一時保存する、ロールバック可能な取引境界を使う、または処理を遅らせる必要がある。

HTTP/1.1、HTTP/2、HTTP/3 ではトレーラーの運び方が異なる。プロキシやフレームワークが捨てたり、異なる形で公開したりする場合もある。実際の経路を通し、最終判断部が処理前に欄を受け取れることを試験で示すべきだ。

同じバイトでも古いことはある

キャッシュ内の応答は昨日と同じバイトを保ち、ダイジェストにも一致できる。それでも鮮度や再検証、古い応答の利用可否は RFC 9111 の別規則が決める。ダイジェストは時間を巻き戻さない。

再送も別問題である。正しい本文、ダイジェスト、署名を持つ要求を二度送れば、三つの検査は二度とも通り得る。時刻窓、nonce、要求 ID、冪等性規則が二度目の実行を止める。

意味の安全性も独立している。構文上正しい設定が危険な権限を与えることも、配布元の摘要と一致するソフトウェアに脆弱性があることもある。整合性は対象を保存するが、その効果を承認しない。

境界を示す負の試験

最初に、有害な本文と正しいダイジェストを送る。整合性検査は成功し、認証または認可は失敗しなければならない。次に本文の一バイトだけを変え、状態変更前に不一致を検出する。

Content-Digest を署名範囲から外した要求と、欄を署名したまま本文だけを変えた要求を試す。複数、未知、非推奨のアルゴリズムも送り、並び順で弱い方式へ降格しないことを確かめる。

圧縮、範囲、表現再構成、各 HTTP 版のトレーラー、古いキャッシュ、正しい署名要求の再送まで通す。目標は一つの緑表示ではない。それぞれの関門が、自分の所有する結論だけを返すことである。