+ 作る
図を読み込んでいます…
1 / 13
図でつながる 認証と暗号の基礎 / 全11章

ハイブリッド暗号と鍵共有 ― 鍵は公開鍵で整え、本文は共通鍵で守る

発行
かえで
版
第2版
改訂
分量
13コマ・4,857字

速いけれど鍵を渡せない共通鍵と、配れるけれど重い公開鍵。二つを組み合わせて大きなデータを守る仕組みを、鍵を包むモデル、HPKE、絵の具でたとえる鍵共有、TLS 1.3 と前方秘匿性まで、動く図でたどります。

速い共通鍵と、配れる公開鍵

第3章の共通鍵暗号は速く、大きなデータも楽に暗号化できます。ただ、送る人と受け取る人が同じ鍵を前もって持っていなければならず、その鍵をどうやって安全に渡すかという問題が残りました。第4章の公開鍵暗号は、この問題を解きます。公開鍵は配ってよい鍵なので、誰でもボブ宛てに暗号化できます。そのかわり計算が重く、一度に扱えるのは小さなデータです。

図のアオイは、50 MB の会議資料をボブへ送りたいところです。共通鍵だけでは鍵を渡せず、公開鍵だけでは大きな資料を扱いにくい。それぞれの得意なところだけを使えないでしょうか。

公開鍵の技術で鍵を整え、本文は共通鍵で守る。この分担を、この章ではハイブリッド暗号と呼びます。前半は「鍵を包んで送る」形で仕組みをつかみ、後半は鍵そのものを送らずに済む鍵共有へ進みます。

  • 速い共通鍵と、配れる公開鍵
  • 人
  • 通信路
  • 人
  • アオイ
  • ボブ
  • 共通鍵:速い でも、鍵を渡す方法がない
  • ボブの公開鍵
  • 本文 会議の資料 50 MB
  • ボブの秘密鍵
  • 公開鍵:鍵を配れる でも、重くて小さなデータ向き
  • 大きな資料を、速く安全にボブへ届けたい

その場限りの鍵 K で本文を暗号化する

まずアオイは、この資料のためだけの共通鍵 K を作ります。K は乱数から作るランダムな値で、ほかの通信には使い回しません。図で資料の右に現れた緑の鍵が K です。

次に、資料の本文を K で暗号化します。使うのは第3章の AEAD(認証付き暗号)です。AEAD は中身を読めなくするだけでなく、検証用のタグも付けます。途中で1ビットでも書き換えられれば、受け取った側でタグが合わなくなり、改ざんに気づけます。図の資料が白から灰色に変わり、読めない暗号文になりました。

共通鍵暗号は速いので、本文が 50 MB でも 5 GB でも、この部分の負担は大きくありません。残る問題は、K をどうやってボブに届けるかだけです。K は AES-256 の鍵なら 32 バイトの、ごく小さな値です。

  • その場限りの鍵 K で本文を暗号化する
  • 人
  • 通信路
  • 人
  • アオイ
  • ボブ
  • ボブの公開鍵
  • 暗号文 AEAD(K) 50 MB
  • ボブの秘密鍵
  • 鍵
  • 鍵 K
  • 使い捨て・ランダム
  • 本文は、その場で作った K の AEAD で暗号化する

小さな K だけを、ボブの公開鍵で包む

ここで公開鍵の出番です。アオイは、ボブが配っている公開鍵を使って K を暗号化します。図の緑の鍵 K が上へ移り、青い錠の付いた包みに変わりました。この包みを開けられるのは、対になる秘密鍵を持つボブだけです。

公開鍵で処理するのは、32 バイトほどの K だけです。重い公開鍵の計算は小さなデータに一度だけ使い、大きな本文には速い共通鍵を使う。これがハイブリッド暗号の分担です。このように鍵を暗号化して相手へ運ぶやり方を鍵輸送(key transport)と呼びます。

前の章で見たとおり、使う公開鍵が本当にボブのものかは、別に確かめておく必要があります。すり替えられた公開鍵で包むと、包みを開けられるのはすり替えた人になってしまいます。

  • 小さな K だけを、ボブの公開鍵で包む
  • 人
  • 通信路
  • 人
  • 錠
  • アオイ
  • 包んだ K
  • ボブの公開鍵
  • ボブ
  • ボブの公開鍵
  • 暗号文 AEAD(K) 50 MB
  • ボブの秘密鍵
  • 重い公開鍵の計算は、小さな K にだけ使う

二つの包みを一緒に送る

アオイは、灰色の暗号文と、青い包みに入った K を、まとめてボブへ送ります。図では大きい包みと小さい包みが通信路を進んでいます。実際には、復号に必要な nonce(一度だけ使う番号)なども一緒に付けます。

通信路の途中で盗み見る人がいても、見えるのはどちらも読めない包みです。K は包まれているので取り出せず、K がなければ本文も開けません。共通鍵 K もボブの秘密鍵も、そのままの形では一度も通信路に出ていません。

ただ、箱を二重にしただけで安全になるわけではありません。どの鍵とどの方式で包んだかを取り違えないこと、受け取った側で改ざんを必ず検証することなど、細かな約束まで守って、ようやく安全な仕組みになります。この点は2ページ後でもう一度触れます。

  • 二つの包みを一緒に送る
  • 人
  • 通信路
  • 人
  • 錠
  • アオイ
  • 包んだ K
  • ボブ
  • ボブの公開鍵
  • 暗号文 AEAD(K) 50 MB
  • ボブの秘密鍵
  • 人
  • 注意
  • どちらも読めない
  • 盗み見る人

ボブは鍵を取り出してから、本文を開く

受け取ったボブは、まず小さい包みを開けます。自分の秘密鍵で包みを開けると、中から K が出てきます。図の青い包みが緑の K に戻りました。

次に、その K で本文を開きます。AEAD の復号では、中身を元に戻すのと同時にタグを確かめ、包みが作られたあとで書き換えられていないかを検証します。図の資料が白に戻り、「改ざんなし」の印が付きました。タグが合わなければ、ボブは本文を一切使わずに捨てます。

ここで分かるのは、本文がボブ以外には読まれず、途中で変わっていないことまでです。公開鍵は誰でも使えるので、送ってきたのが本当にアオイなのかは、この仕組みだけでは分かりません。送り主を確かめたいときは、送信者を認証する方式や、第6章の電子署名を組み合わせます。

  • ボブは鍵を取り出してから、本文を開く
  • 人
  • 通信路
  • 秘密鍵で取り出した K
  • 人
  • 鍵
  • アオイ
  • 鍵 K
  • ボブ
  • ボブの公開鍵
  • 本文 会議の資料 50 MB
  • ボブの秘密鍵
  • 改ざんなし
  • 鍵 → 本文の順に開き、改ざんがないかも確かめる

実際には HPKE を使う

ここまでの「K を作って包む」流れは、仕組みをつかむためのモデルです。暗号の部品を自分で組み合わせると、鍵の使い回しや検証の抜けといった、見えにくい穴ができがちです。実際に作るときは、確立した仕様と、それを実装したライブラリを使います。代表的な仕様が HPKE(Hybrid Public Key Encryption、RFC 9180)です。

HPKE は3つの部品でできています。KEM(鍵カプセル化)は、ボブの公開鍵から「鍵の素」になる秘密の値と、それをボブだけが取り出せる形にした enc(カプセル)を同時に作ります。KDF(鍵導出関数)は、その秘密の値から AEAD 用の鍵を導きます。最後に AEAD が本文を暗号化します。

図のとおり、HPKE は先に作った K を暗号化するのではなく、KEM の結果から鍵を導き出します。ボブは自分の秘密鍵と enc から同じ秘密の値を得て、同じ手順で同じ鍵を導きます。なお HPKE の基本の使い方(base モード)も送り主の確認はしないので、必要なら送信者を認証するモードを選びます。

  • 実際には HPKE を使う
  • HPKE(RFC 9180)の中身
  • ボブの公開鍵
  • KEM 鍵の素を作る
  • KDF 鍵を導く
  • 鍵
  • 導いた鍵
  • enc(カプセル)
  • 本文
  • AEAD 本文を暗号化
  • 暗号文
  • ボブへ送るのは enc と暗号文。ボブは秘密鍵と enc から同じ鍵を導く

鍵を送らずに、同じ鍵を作る

包んで送るやり方とは別に、鍵そのものを一度も送らずに、二人が同じ鍵を計算で作り出す方法があります。これを鍵共有と呼び、代表が Diffie–Hellman 鍵共有(DH)です。仕組みは、絵の具を混ぜるたとえでよく説明されます。

まず、誰もが知っている「共通の色」を決めます。図の真ん中の黄色です。アオイとボブは、それぞれ人に見せない「秘密の色」を一つずつ選びます。アオイは赤、ボブは青です。そして共通の色に自分の秘密の色を混ぜ、図のオレンジと緑の「混ぜた色」を作ります。

ここで大事なのは、混ぜた色から元の秘密の色を取り出すのはとても難しい、という性質です。絵の具は一度混ぜると分けられません。DH では、これに当たるのが「計算するのは簡単だが、逆にたどるのは現実的にできない」という数学の性質です。

  • 鍵を送らずに、同じ鍵を作る
  • 人
  • 通信路(誰でも見える)
  • 人
  • アオイ
  • 共通の色(公開)
  • ボブ
  • 秘密の色(赤)
  • 混ぜた色
  • 混ぜた色
  • 秘密の色(青)
  • 混ぜた色から、秘密の色を取り出すのは難しい

通信路を渡るのは、混ぜた色だけ

次に、二人は混ぜた色を交換します。図では、アオイのオレンジがボブへ、ボブの緑がアオイへ、通信路の上を進んでいます。秘密の色は、どちらも手元から動いていません。

盗み見る人に見えるのは、共通の色と、二つの混ぜた色です。混ぜた色から秘密の色は分けられないので、盗み見る人は秘密の色を手に入れられません。交換するのが「見られてもよい値」だけ、という点は第4章の公開鍵とよく似ています。実際、DH で交換する値は、それぞれが作った鍵ペアの公開鍵にあたり、秘密の色は秘密鍵にあたります。

本物の DH では、色の代わりに数を使います。今よく使われるのは楕円曲線という数学を使う方式で、たとえば X25519 は RFC 7748 にまとめられています。

  • 通信路を渡るのは、混ぜた色だけ
  • 人
  • 通信路(誰でも見える)
  • 人
  • アオイ
  • 共通の色(公開)
  • ボブ
  • 秘密の色(赤)
  • 混ぜた色
  • 混ぜた色
  • 秘密の色(青)
  • 人
  • 注意
  • 盗み見る人
  • 見えるのは、共通の色と混ぜた色だけ

両端に同じ色ができる

受け取った混ぜた色に、自分の秘密の色を混ぜます。アオイは「ボブから届いた緑+赤」、ボブは「アオイから届いたオレンジ+青」です。どちらも中身は「黄+赤+青」なので、図の両端に同じ茶色が現れます。この同じ色が共有秘密で、ここから KDF で通信用の共通鍵を導きます。鍵そのものは一度も通信路を通っていません。

たとえには限界もあります。本物の DH は絵の具ではなく数の計算で、「分けられない」のは逆算が数学的に難しいからです。もっと大事な違いは、色を交換しただけでは、相手が本当にボブかは分からないことです。間に入った人がボブのふりをして自分の色を渡せば、アオイはその人と鍵を共有してしまいます。そのため実際の通信では、交換した値に相手が署名して、本物であることを示す仕組みを組み合わせます。

  • 両端に同じ色ができる
  • 人
  • 通信路(誰でも見える)
  • 人
  • アオイ
  • 共通の色(公開)
  • ボブ
  • 秘密の色(赤)
  • 届いた色
  • 届いた色
  • 秘密の色(青)
  • 人
  • 注意
  • 盗み見る人
  • 同じ色(共有秘密)
  • 同じ色(共有秘密)
  • 鍵そのものは、一度も通信路を通らない

TLS 1.3 は毎回、鍵を導く

ブラウザーが HTTPS でサイトにつなぐとき、裏では TLS 1.3(RFC 8446)が動いています。一般的な接続で使われるのが ECDHE です。楕円曲線(EC)を使う DH を、接続ごとに作り直す一時的な(Ephemeral)鍵ペアで行う、という意味です。

図のブラウザーとサーバーは、接続のたびに新しい一時的な秘密を作り、その公開側の値(key_share)を交換します。そして、自分の秘密と相手の値から同じ共有秘密を計算し、KDF で通信用の鍵を導きます。共通鍵そのものを公開鍵で暗号化して送っているのではない点が、前半のモデルとの違いです。

鍵共有だけでは、前のページのとおり相手が本物か分かりません。そこでサーバーは証明書を送り、自分の長期の秘密鍵で、鍵共有の値を含むそれまでのやりとり全体に署名します。ブラウザーは証明書と署名を確かめて、相手が本物のサイトだと判断します。証明書と署名の中身は、第6章と第7章で詳しく見ます。(再接続などで別の鍵の決め方を使うこともありますが、図は代表的な形です。)

  • TLS 1.3 は毎回、鍵を導く
  • ブラウザ
  • 通信路
  • サーバー
  • ブラウザー
  • サーバー
  • 一時的な秘密 a
  • 一時的な秘密 b
  • ブラウザーの key_share
  • サーバーの key_share
  • 共有秘密 → KDF 通信用の鍵
  • 証明書と署名で 本物か確かめる
  • 共有秘密 → KDF 通信用の鍵
  • 共通鍵そのものを、公開鍵で暗号化して送ってはいない

使い捨ての鍵が、過去の通信を守る

ECDHE の一時的な秘密は、接続が終われば捨てます。図の灰色の通信 1・2・3 は、それぞれ別の使い捨ての鍵で守られ、その鍵はもうどこにも残っていません。

ここで、盗み見る人が暗号文をすべて保存していたとします。そして後日、サーバーの長期の秘密鍵が漏れてしまいました。それでも過去の通信は読めません。長期の秘密鍵は署名で本人を示すためのもので、通信の鍵を作る材料には使われていないからです。この性質を前方秘匿性(forward secrecy)と呼びます。

もし前半のモデルのように、サーバーの長期の公開鍵で毎回 K を包んでいたら、事情が変わります。保存しておいた包みを、あとから漏れた秘密鍵で開ければ、過去の K がすべて出てきてしまうからです。TLS 1.3 が固定の鍵を使う RSA や DH の鍵交換をやめ、公開鍵を使う鍵交換をすべて前方秘匿性のある形にしたのは、この弱点をなくすためです。

  • 使い捨ての鍵が、過去の通信を守る
  • 通信 1 鍵は使い捨て
  • 通信 2 鍵は使い捨て
  • 通信 3 鍵は使い捨て
  • 後日 長期の秘密鍵が漏れる
  • 時間
  • 人
  • 盗み見る人:暗号文をすべて保存していた
  • それでも、過去の通信は読めない
  • この性質を「前方秘匿性」と呼ぶ

もう一つの「ハイブリッド」

暗号の話では、「ハイブリッド」がこれまでの暗号と耐量子暗号を組み合わせる意味でも使われます。耐量子暗号は、将来大きな量子コンピューターができても破られにくいように作られた新しい方式で、その一つが NIST が標準にした ML-KEM(FIPS 203)です。たとえば TLS では、X25519 の鍵共有と ML-KEM-768 を同時に行い、二つの共有秘密をつなげてから鍵を導く X25519MLKEM768 という組み合わせが、ブラウザーなどで使われ始めています。片方に弱点が見つかっても、もう片方が持ちこたえれば通信は守られる、という考え方です。この組み合わせは、IETF で標準化が進められている仕様(Internet-Draft)にまとめられています。

本章の「ハイブリッド」は公開鍵の技術と共通鍵暗号の分担のことで、こちらは鍵共有の方式どうしの組み合わせです。言葉が同じでも指すものが違うので、文脈で見分けてください。

  • もう一つの「ハイブリッド」
  • 例:TLS の X25519MLKEM768
  • X25519 (これまでの楕円曲線)
  • 二つの共有秘密 をつなげる
  • KDF で 通信用の鍵を導く
  • ML-KEM-768 (耐量子暗号)
  • 片方が破られても、もう片方が持ちこたえれば守られる
  • 本章の「公開鍵+共通鍵」のハイブリッドとは別の意味

まとめ:いつも鍵を包んで送るのか

この章では、共通鍵暗号と公開鍵の技術の分担を見てきました。重い公開鍵の計算は鍵を整える小さな仕事だけに使い、大きな本文は速い共通鍵の AEAD で守ります。

では、ハイブリッド暗号なら、いつも鍵を暗号化して送るのでしょうか。答えは「いいえ」です。前半のモデルのように K を公開鍵で包んで送る形もありますが、HPKE は KEM の結果から鍵を導き、TLS 1.3 は ECDHE の鍵共有で両端に同じ鍵を作ります。どれも、共通鍵をそのままの形で通信路に流さずに、二人が同じ鍵を持てるようにする工夫です。図の上の二つの道は、どちらも下の「本文は共通鍵の AEAD で守る」に行き着きます。

ただ、ここまでの仕組みが守るのは秘密です。相手が本物かどうかは、証明書と署名に任せていました。次の章では、秘密を守るのではなく、誰が作ったか、途中で書き換えられていないかを確かめる電子署名を見ていきます。

  • まとめ:いつも鍵を包んで送るのか
  • 鍵を包む(鍵輸送) K を公開鍵で包んで送る
  • 鍵を導く(KEM・鍵共有) HPKE・ECDHE(TLS 1.3)
  • 本文は共通鍵の AEAD で守る
  • 答え:いいえ。包む形も、導く形もある
  • 次の章:誰が作ったかを確かめる電子署名へ

0 件のコメント

読み込み中…

権利侵害・不適切な内容の連絡: [email protected]