TL

前方秘匿性(PFS)と Signal のダブルラチェットの原理

鍵が一度漏れても過去のメッセージは守られ、未来の安全も自動で回復する。Signal のダブルラチェットがどう前方秘匿性と post-compromise security を両立させるかを原理から押さえられます。

応用前方秘匿性SignalダブルラチェットX3DH鍵交換最終更新: 2026-06-21
TL;DR要点だけ先に
  • 1.前方秘匿性(PFS)は「いま鍵が漏れても過去は守る」性質。各メッセージ鍵を使い終わったら破棄し、KDF の一方向性で古い鍵を遡って復元できないようにする。
  • 2.post-compromise security(PCS)はその逆で「過去に漏れても未来は回復する」性質。新しい DH 交換を定期的に注入し、攻撃者が知らない乱数で鍵チェーンをリセットする。
  • 3.Signal は X3DH で最初の共有秘密を作り、対称ラチェット(PFS 担当)と DH ラチェット(PCS 担当)を組み合わせたダブルラチェットで両性質を同時に満たす。

解きたい問題:鍵は「いつか必ず漏れる」前提で守る

暗号の現実的な脅威モデルでは、鍵は永久に秘密でいられません。端末の押収、マルウェア、メモリダンプ――いつか鍵が攻撃者の手に渡る。問題は「漏れたら終わり」にしないことです。ここで二つの異なる性質が要ります。

  • 前方秘匿性(PFS, Perfect Forward Secrecy):いま鍵が漏れても、それ以前に送った過去メッセージは復号できない。
  • post-compromise security(PCS, 将来回復性):いま鍵が漏れても、その後いずれメッセージの安全が自動で回復する。

ECDHE が TLS にもたらすのは PFS だけです。長時間続く一本のセッションでは「途中で鍵が漏れたら、それ以降ずっと丸見え」という弱点が残ります。チャットのように何日も続く会話では、PFS に加えて PCS が欲しい。Signal のダブルラチェットは、この二つをメッセージ単位で達成する仕組みです。

PFS の原理:一方向 KDF で鍵を「捨てて、戻れなくする」

PFS の核心は単純です。各メッセージを別々の鍵で暗号化し、使い終わった鍵を即座に破棄する。そして古い鍵を新しい鍵から逆算できなくする。 これを支えるのが鍵導出関数(KDF)の一方向性です。

chain_key_0 ─KDF─▶ (chain_key_1, message_key_0)
chain_key_1 ─KDF─▶ (chain_key_2, message_key_1)
chain_key_2 ─KDF─▶ (chain_key_3, message_key_2)
   ...
各 message_key で1通だけ暗号化し、使ったら破棄する

これが**対称ラチェット(symmetric ratchet)**です。チェーン鍵を KDF に通して「次のチェーン鍵」と「今回のメッセージ鍵」を取り出し、自分は次のチェーン鍵だけを保持します。KDF はハッシュ系の一方向関数なので、chain_key_2 を奪っても chain_key_1 や過去の message_key_0 は復元できません。歯車(ratchet)が前にしか回らないのが名前の由来です。

メッセージ鍵は1通使い切り

message_key は1メッセージの暗号化(実体は AEAD)に使い、直後に破棄します。受信側も復号したらその鍵を捨てる。だから端末が後で奪われても、過去メッセージの鍵はもうメモリ上に存在せず、チェーン鍵から遡って作り直すこともできません。

ただし対称ラチェットだけでは PCS は得られません。攻撃者がチェーン鍵そのものを奪えば、そこから先のメッセージ鍵は全部 KDF で前送りに計算できてしまう。未来が守れないのです。ここで二つ目のラチェットが要ります。

PCS の原理:DH を注入してチェーンをリセットする

未来を回復する唯一の方法は、攻撃者が知らない新しい乱数を鍵チェーンに混ぜることです。それを供給するのが Diffie-Hellman です。

DH ラチェットでは、両者がエフェメラルな DH 鍵ペアを持ち、メッセージのやり取りに自分の新しい DH 公開鍵を相乗りさせます。相手の新しい公開鍵を受け取るたびに、自分の秘密鍵との間で新しい DH 共有秘密を計算し、それをルート鍵に混ぜてチェーンを丸ごと作り直します。

受信した相手の新 DH 公開鍵 + 自分の DH 秘密鍵
        │
     DH 計算 → 新しい共有秘密
        │
root_key ─KDF─▶ (新 root_key, 新 chain_key)   ← チェーンがリセットされる

肝心なのは、攻撃者がいま全状態(チェーン鍵もルート鍵も)を奪っても、次の DH ラチェットで両者が生成する DH 秘密鍵は新しい乱数だという点です。攻撃者はその秘密鍵を知らないため、新しい共有秘密を計算できず、リセット後のルート鍵を追えなくなる。一度の DH ステップを「両者が無事に通過」すれば、そこで攻撃者は締め出され、安全が回復します。これが PCS の正体です。

PCS は「条件付き」の回復

PCS は無条件ではありません。回復には、攻撃者に邪魔されず両者が新しい DH 鍵を交換できる必要があります。攻撃者が常時メッセージを改ざん・遮断できる能動的中間者であり続ける限り、回復は妨げられます。PCS が守るのは「受動的に状態を一度盗み見たが、その後は手を引いた攻撃者」に対する自己修復だと理解してください。

ダブルラチェット:二つを噛み合わせる

ダブルラチェットは、この対称ラチェットと DH ラチェットを階層的に組み合わせたものです。役割分担が明快です。

二段構え。対称ラチェットが細かい粒度で過去を守り、DH ラチェットが大きな粒度で未来を回復する。
観点対称ラチェットDH ラチェット
回す単位メッセージ1通ごと通信の向きが切り替わるごと
供給する乱数なし(KDF の前送りのみ)新しい DH 共有秘密
主に担う性質前方秘匿性(PFS)将来回復性(PCS)
守る対象過去のメッセージ鍵将来のチェーン全体
入力現在のチェーン鍵相手の新 DH 公開鍵 + ルート鍵

実際の流れはこうです。送信チェーン・受信チェーンの中では対称ラチェットがメッセージごとに回り、PFS を細かく刻む。会話の向きが相手→自分に切り替わると、相手の新しい DH 公開鍵が届くので DH ラチェットが回り、ルート鍵と両チェーンが作り直されて PCS を回復する。両者は交互に DH 鍵を更新し合うので、会話が続く限り定期的に「攻撃者を締め出す機会」が訪れます。

ルート鍵チェーン(DH ラチェットが進める)
  root_key ─DH─▶ root_key' ─DH─▶ root_key'' ...
      │              │
   送信/受信       送信/受信
   チェーン鍵      チェーン鍵
      │              │
   対称ラチェット  対称ラチェット   ← メッセージ鍵を1通ずつ生成
順序ズレ・欠落への耐性

ネットワークではメッセージが前後したり落ちたりします。ダブルラチェットは、まだ来ていない番号のメッセージ鍵を先に計算してスキップ鍵として保管できます。後から古い番号が届いても、保管した鍵で復号可能。これがあるため、非同期で順不同なモバイル通信でもラチェットが破綻しません。

最初の鍵はどう作る:X3DH

ラチェットを回すには、最初の共有秘密(初期ルート鍵)が必要です。ところが相手はオフラインかもしれない。これを非同期で解くのが **X3DH(Extended Triple Diffie-Hellman)**です。

各ユーザーはあらかじめサーバーに鍵バンドルを預けます。長期の身元鍵(IK)、中期の署名付き事前鍵(SPK)、使い捨ての一回限り事前鍵(OPK)です。送信者は相手のバンドルを取得し、自分の身元鍵とエフェメラル鍵を使って複数の DH を実行し、その結果を連結して KDF に通すことで初期共有秘密を導きます。

DH1 = DH(送信者IK,   相手SPK)   ← 送信者の身元を共有秘密に結ぶ
DH2 = DH(送信者EK,   相手IK)    ← 相手の身元を共有秘密に結ぶ
DH3 = DH(送信者EK,   相手SPK)   ← 前方秘匿性に寄与
DH4 = DH(送信者EK,   相手OPK)   ← 使い捨て鍵で各セッションを独立化

初期共有秘密 = KDF(DH1 ‖ DH2 ‖ DH3 ‖ DH4)
→ この値をダブルラチェットの最初の root_key にする

なぜ DH を複数組むのか。それぞれの身元鍵を絡めた DH(DH1 が送信者の IK を、DH2 が相手の IK を共有秘密に織り込む)が相互認証を担い、なりすましを防ぎます。一方、エフェメラル鍵と一回限り事前鍵を絡めた DH(DH3/DH4)がPFS とセッションの独立性を与えます。SPK は身元鍵で署名されているため、電子署名による相手認証も成立します。こうして相手がオフラインでも、認証付きで前方秘匿な初期鍵を一発で確立できるのです。

認証なしのラチェットは無意味

ダブルラチェットも X3DH も、相手の身元鍵が本物だと信じられて初めて成立します。身元鍵の検証(Signal の「安全番号」照合)を怠ると、能動的中間者が最初から両者になりすませてしまい、PFS も PCS も攻撃者の手の中で完結します。鍵共有・前方秘匿性・相手認証は別問題だという原則はここでも効きます。

まとめ

前方秘匿性は KDF の一方向性で過去の鍵を不可逆に捨てることで、post-compromise security は 新しい DH の乱数を注入してチェーンをリセットすることで達成されます。Signal のダブルラチェットは、メッセージ単位で前者を刻む対称ラチェットと、向きの切り替わりで後者を回復する DH ラチェットを噛み合わせ、両性質をメッセージ粒度で同時に満たします。最初の共有秘密は X3DH が非同期かつ認証付きで確立し、以降のすべての鍵がそこから派生します。

土台となる鍵共有とエフェメラル鍵の考え方は Diffie-Hellman、メッセージ本体を守る暗号は AEAD、鍵チェーンを支える一方向関数は ハッシュ関数の内部構造 と併せて押さえると、なぜこの設計で「漏れても守れる」のかが原理から腑に落ちます。

セキュリティ Article

前方秘匿性(PFS)と Signal のダブルラチェットの原理を実務で読む

TL;DRは入口です。実際に選ぶ・使う段階では、何を解決するか、何と比較するか、導入後にどこで詰まるかまで見る必要があります。

解決すること

前方秘匿性

比較で見る軸

難易度: advanced / カテゴリ: セキュリティ / タグ数: 5

導入後に効く点

post-compromise security(PCS)はその逆で「過去に漏れても未来は回復する」性質。新しい DH 交換を定期的に注入し、攻撃者が知らない乱数で鍵チェーンをリセットする。

先に潰すリスク

用語だけ覚えても、設計・実装・運用でどこに効くかを確認しないと判断を誤る。

数字・仕様の読み方
難易度
advanced
カテゴリ
セキュリティ
タグ数
5

判断チェックリスト

  • 自社の用途が「前方秘匿性 / Signal」に近いか確認する。
  • 強みである「前方秘匿性(PFS)は「いま鍵が漏れても過去は守る」性質。各メッセージ鍵を使い終わったら破棄し、KDF の一方向性で古い鍵を遡って復元できないようにする。」が本当に評価軸になるか確認する。
  • 注意点の「用語だけ覚えても、設計・実装・運用でどこに効くかを確認しないと判断を誤る。」を運用で吸収できるか確認する。
  • 公開値や仕様値は、対象プラン・対象機種・対象リージョンまで確認する。
  • 既存システム、ID、ネットワーク、監視、バックアップとの接続方法を先に洗い出す。
  • 小さく試してから、本番移行、権限設計、障害時手順、コスト監視を決める。

次に確認する観点

前方秘匿性SignalダブルラチェットX3DH鍵交換前方秘匿性Signalダブルラチェット
参考: 公式情報