要約
- RFC 1446 の SNMPv2 認証では、共有鍵を用いた MD5 ダイジェストの照合と、メッセージが許容寿命内にあるかという時宜性の判定が別々に行われた。ダイジェストの一致だけでは新しさを証明できなかった。
- 同じ秘密認証鍵を使う間、
partyAuthClockは減少してはならない。時計だけを戻すと、すでに閉じたタイムスタンプ領域が開き、保存された古いメッセージが再び受理条件を満たし得るためである。 - 復旧時に守るべき対象は、主体の識別、鍵の世代、単調な時間を合わせたセキュリティ上の時代だった。後の RFC 3414 は、権威エンジン ID、起動回数、起動内時間へ表現を変えたが、暗号的な正しさと時宜性を同一視しなかった。
「もう過ぎた」を何が証明するのか
管理対象のエージェントが、認証時計 70,000 の時点で停止したとする。その少し前、時刻 69,500 を持つ要求がネットワークを流れ、第三者に記録された。許容寿命が 300 秒なら、受信側の時計が 69,800 を越えた後、その要求は古すぎて退けられる。
ところが再起動時、エージェントが保存済みの 69,400 を読み戻し、秘密鍵は以前と同じだったらどうなるか。69,500 の要求は再び窓の内側に見える。送信者は再送していない。内容もダイジェストも変わっていない。受信側が「現在」を後ろへ動かしたため、過去のパケットが若返ったのである。
この問題を、時計の精度だけの話にすると核心を逃す。数秒のずれを直すことと、同じ秘密の下ですでに通過した範囲へ戻ることは違う。リプレイ耐性はメッセージ単体の属性ではなく、受信側が保持する履歴状態との関係で成立する。古いダイジェストは正しいまま保存できる。だからこそ、受信側がどの時代にいるかを忘れないことが必要だった。
RFC 1446 が示した不変条件は簡潔である。一つの主体が同じ秘密認証鍵を用いる間、その認証時計は非減少でなければならない。どうしても値を下げるなら、鍵も同時に変える。新しい鍵は、同じ数値の時刻が以前とは別の暗号的時代に属することを示す切れ目となる。
ダイジェスト判定のあとにも門があった
RFC 1446 は 1993 年 4 月に Standards Track 文書として公開され、現在は Historic に分類されている。SNMPv2 のために一つの認証プロトコルと一つのプライバシープロトコルを定義した。v2md5AuthProtocol を用いる主体では、16 オクテットの秘密認証材料と MD5 による 128 ビットのダイジェストが使われた。
送信側はまず、ダイジェスト欄に秘密を一時的に入れ、その形の認証メッセージを符号化してハッシュする。送出時には秘密を計算結果で置き換える。受信側は受け取ったダイジェストを取り出し、自分が保持する秘密鍵を所定の欄へ戻して同じ形を再構成し、計算結果を比較する。不一致なら snmpStatsWrongDigestValues が増え、メッセージは認証に失敗する。
ただし、受信側が参照する状態は鍵だけではない。送信元主体についてローカルに記録した認証時計と寿命も読み出し、メッセージ内の時刻を評価する。拒否条件は次の関係だった。
authSrcTimestamp + 寿命 < ローカル認証時計
この条件に当てはまれば snmpStatsNotInLifetimes が増え、メッセージは先へ進めない。ダイジェストが一致するメッセージ同士でも、一方は時間内、もう一方は期限外になり得る。反対に、十分新しくてもダイジェストが違えば失敗する。二つの検査は同じ結果を重ねて確認するのではなく、異なる失敗を排除していた。
運用記録も同じ解像度を保つ必要がある。ダイジェスト一致は、特定の受信バイト列が、その時点の鍵設定の下で仕様の完全性・出所検査を通ったことを支える。時刻比較は、その受信側の窓に入ったか否かを支える。しかし、どちらからもアクセス許可、操作の実行、機器状態の変化、再起動後の永続性までは導けない。
「認証済み」という一語だけを残すと、どの門を通り、どの門がまだ残っていたかが消える。必要なのは、主体、鍵世代、時計または起動世代、適用した窓、正確なメッセージ、ダイジェスト結果、時刻結果を結び、その後のアクセス判断、応答、外部状態の観測を別に保つことである。
寿命を広げると静かになるが、安全になるわけではない
認証メッセージには送信元と宛先の認証タイムスタンプが一秒単位で含まれた。partyAuthLifetime はネットワークが自然に決める値ではなく、管理者が受け入れる最大遅延だった。RFC 1446 は、時計精度、往復遅延、確認頻度が許す限り小さくするよう求めた。
短い窓は古さを厳密に区切る一方、遅延や時計差に弱い。長い窓は正常な通信を通しやすい一方、記録されたメッセージが利用可能な時間を延ばす。期限外エラーを減らすために寿命を増やせば、監視画面はすぐ静かになる。しかしそれは誤差吸収だけでなく、リプレイ可能性に関する方針変更でもある。
窓の内側にあることは、一度しか届いていないことを意味しない。同一のコピーが複数回届いても、それぞれが時間内であり得る。状態を変えるメッセージについて、RFC は肯定応答を待つか、該当時間が過ぎるまで後続を送らないよう勧めた。ダイジェストと時計は、データグラムを自動的に順序保証付きの取引へ変えるものではなかった。
時宜性とダイジェストを通過した後には、アクセス方針の判断があった。何らかのアクセスが許された場合に限り、ローカル記録より大きい認証済みタイムスタンプが主体の時計認識を選択的に前進させた。誰でも時計を教えられるわけではない一方、時刻更新そのものが操作権限や実際の効果を証明するわけでもなかった。
鍵交換は古い区間への橋を落とした
時計だけを戻したとき、捕捉済みメッセージには二つの利点が残る。古い鍵に対応する正しいダイジェストと、かつて受理されたタイムスタンプである。時刻範囲を開き直せば後者が復活し、鍵を維持すれば前者も有効なままだ。
鍵を同時に変えると、この組み合わせが崩れる。古いタイムスタンプが数値上は新しい窓に近づいても、以前の秘密で作られたダイジェストは新しい秘密に合わない。時計の巻き戻しと鍵交換が一つの状態遷移でなければならない理由は、どちらか片方では古い受理関係の半分を温存してしまうからである。
RFC 1447 のパーティ MIB は、この原則を partyAuthClock の定義に明記した。主体の秘密認証鍵を同時に変更しない限り値を減らしてはならない。partyAuthLifetime は受容する秒数を表した。見かけ上は別々の管理オブジェクトでも、運用上は鍵世代を含む一つの時代を構成していた。
新しい鍵を書き込む要求を送っただけでは、時代の移行は完了しない。管理局が値を決め、要求を送り、相手が受け取り、採用を確認し、他の責任管理局へ伝え、旧鍵を廃棄する。それぞれは異なる出来事である。配送が確かになるまで新旧両方の秘密を保持する必要があり、その管理局自身が再起動しても二つの値を失ってはならない場合がある。
旧鍵を早く捨てれば、まだ移行していない相手との通信が止まる。長く残しすぎれば、複数の信頼時代が不要に共存する。「鍵変更要求を受理した」というログは、この移行列の一地点しか証明しない。
最初の時刻は、信用せずに利用する
RFC 1446 は時計がおおまかに同期していること、そして少なくとも一つの責任管理局が時計同期と秘密配布を担うことを前提とした。秘密を変えない通常の同期では、遅い側の認識を速い側へ進める。速い時計を戻して同じ鍵の過去を開く方法は採らない。
興味深いのは、管理局が相手との時計差をまだ知らない場面である。認証付き要求を通す基準自体が不明なため、まず未認証で時計値を取得できた。その値は同期候補として使えるが、証拠として完成してはいない。採用後、認証付きの取得を行い、値を確認する必要があった。
最初の応答は弱いから捨てるのではない。探索に必要な弱い観測として扱う。次の応答は共有秘密に結び付いた確認であり、別の証拠である。二つを一つの「同期成功」に丸めると、信頼がどこから加わったか分からなくなる。
責任管理局が複数あれば、さらに調整が要る。一局が知る鍵世代と時計を、別の一局が知らないかもしれない。プロトコルは局所的な協調を要求できても、誰が移行を開始し、誰の確認で終了とし、どの証拠で旧鍵を捨てるかまでは組織が決めなければならなかった。
再起動後にも過去を区別できるか
RFC 1446 は、各主体の識別情報、認証時計、秘密認証鍵、秘密プライバシー鍵について、不揮発で破壊されにくい表現を要求した。可能であれば寿命も同様に守るべきとした。フィールドがデータベースに存在するだけでは足りない。故障を越えて最新の関係が残る必要がある。
実装はバッテリーで時計を動かし続けてもよい。一定間隔で不揮発記憶へ値を保存し、再起動時に前方へ余裕を持って飛ばす方法もある。目的は失われた秒を正確に再現することではない。同じ鍵がすでに使った時刻領域へ戻らないことである。
長期停止の間に主体時計が最大値へ達した場合、時計は最大で止まる。その後に送るべき認証管理要求は、少なくとも時計と秘密認証鍵を変更するものに限られた。最大値は現行時代の終端であり、単なるゼロリセットの合図ではない。
保護されたパラメータを失った場合、仕様はランダムな置換値を作り、手作業で再配布しなければ通信できない状態へ移すよう求めた。推測で連続性を作れば可用性は戻っても、どの過去を除外できているか証明できない。明示的な停止を選ぶ設計だった。
SNMPv3 は時計を再起動できる形にした
後の RFC 3414 による User-based Security Model は、時宜性の中心を権威 SNMP エンジンに置いた。snmpEngineID がエンジンを識別し、snmpEngineBoots が再起動または再初期化の回数を数え、snmpEngineTime が現在の起動からの秒数を数える。エンジン ID と起動回数は不揮発でなければならない。
起動回数が先に増えるため、起動内タイマーはゼロに戻せる。以前の起動で時刻 100 だったメッセージと、現在の起動で時刻 100 のメッセージは、同じ数値でも違う時代に属する。権威受信側は起動回数が違うメッセージ、または固定 150 秒の窓から外れるメッセージを拒否する。
表現は変わったが、暗号値が時宜性を兼ねるようになったわけではない。認証と時間は別に検査された。最新の起動回数を確定できない場合、エンジンはカウンターを最大値に張り付かせ、手動介入で新しいエンジン ID またはユーザー秘密を確立するまで認証メッセージを時間検査で失敗させた。
RFC 3414 が RFC 1446 を直接置き換えたわけではなく、系譜には中間の仕様がある。ここで重要なのは構造の比較だ。前者は連続するパーティ時計の後退を鍵交換で断ち、後者は起動内タイマーのリセットを永続する起動回数で区別した。いずれも、正しいダイジェストだけでは、そのメッセージが現在の履歴に属することを証明できないと考えた。
参考資料
会員向け解説
プロフィールの詳細
適切な会員レベルでログインすると、解説全文と出典メモをご覧いただけます。
Strategic Circle 限定
Strategic Circle
すべての読者に公開されています。参加してログインすると プロフィール解説 を閲覧できます。
Strategic Circle に参加Leadership Alliance 会員限定
Leadership Alliance
対象となる IP 資産の所有者・管理者向けです。ログインすると Leadership Alliance の解説を閲覧できます。
Leadership Alliance に参加
