🔐

やはりお前らの「公開鍵暗号」はまちがっている。

2023/03/06に公開
1

※タイトルの元ネタは以下の作品です。

https://gagagabunko.jp/specal/oregairu/

はじめに

この記事は、公開鍵暗号の全体感を正しく理解するためのものです。数学的な部分や具体的なアルゴリズムは説明しません。気になる方は最後に紹介するオススメ書籍をご覧ください。

少し長いですが、図が多いだけで文字数はそこまで多くありません。また、専門的な言葉はなるべく使わないようにしています。

ただしSSHやTLSといった通信プロトコルの名称が登場します。知らない方は、通信内容の暗号化や通信相手の認証(本人確認)をするためのプロトコルだと理解して読み進めてください。

公開鍵暗号の前に:暗号技術とは

公開鍵暗号は暗号技術の一部です。暗号と聞くと、以下のようなものを想像するかもしれません。

これは情報の機密性を守るための「暗号化」という技術ですが、実は「暗号技術」と言った場合にはもっと広い意味を持ちます。まずはこれを受けて入れてください。

念のため補足しておくと、「暗号化の用途がいろいろある」と言っているのではありません。「暗号技術の中の一つが暗号化である」と言っています。

公開鍵暗号とは

公開鍵暗号とは、暗号技術の中で、公開情報と秘密情報を組み合わせて実現するものです。公開鍵暗号の多くは数学的な問題に基づいています。

しつこいようですが、ここで言う暗号技術は暗号化に限りません。他にも「鍵共有」や「署名」という技術があり、これらも「公開鍵暗号」です。鍵共有や署名という言葉が突然出てきましたが、これから説明するので安心してください。

鍵とは

そもそも、公開鍵暗号の「鍵」とは何なのでしょうか?

ここではシンプルに、「暗号技術を使用するために必要な何かしらの値」とだけ理解してください。

暗号で鍵と言うと、ドアを開けたり閉めたりするための鍵、あるいは南京錠のようなものを想像する方がいるかもしれません。しかしこのイメージは暗号化を考える場合のみ有効です。公開鍵暗号全体を考える場合には理解の妨げになるので、今回は忘れましょう。

暗号化

まずは公開鍵暗号と聞いて多くの方がイメージするであろう暗号化について説明します。

これは「公開鍵で暗号化し、秘密鍵で復号する」という技術で、以下のような流れで使います。

  1. (ボブ)秘密鍵と公開鍵のペアを生成
  2. (ボブ)暗号化に使う公開鍵をアリスに送信
    • 復号に使う秘密鍵はボブだけの秘密にする
  3. (アリス)公開鍵を使ってメッセージを暗号化
  4. (アリス)暗号文をボブに送信
  5. (ボブ)秘密鍵を使って暗号文を復号

暗号文が盗まれたとしても情報が漏れることはありません。復号に使う秘密鍵がボブだけの秘密だからです。これが暗号化の機能です。

なお秘密鍵と公開鍵は適当に選べば良いわけではありません。2つの鍵には数学的な繋がりがあるので、上手いこと計算すると元のメッセージに戻るわけです。

どこで使われているか?

実は、「公開鍵で暗号化し、秘密鍵で復号する」というタイプの暗号化はあまり使われていません[1]

念のため補足しておくと、SSHやTLSでもほぼ使われていません。SSHやTLSの説明で「公開鍵を使って暗号化」と出てきたら間違いもしくは古い情報である可能性が高いです。

ここまでを図にすると以下のようになります。

鍵共有

暗号化のところで、「公開鍵で暗号化し、秘密鍵で復号する」タイプの暗号化はあまり使われないと言いました。しかし世の中ではさまざまな通信が暗号化されています。これはどういうことでしょうか?

実は通信の暗号化では「共通鍵暗号」というものが使われる場合が多いです。共通鍵暗号とは、暗号化と復号に同じ鍵を使う暗号化方式です。なお「公開鍵暗号」という言葉が広い意味でも使われるのに対し、「共通鍵暗号」と言ったら暗号化を指す場合が多いです。

さて、アリスとボブが共通鍵暗号を使って暗号化通信を始めるためには、2人で同じ鍵を安全に共有しなくてはなりません。そこで活躍するのがDH鍵共有という技術です。DHとはこの方法を発見した研究者2名の頭文字です。

DH鍵共有の流れは以下です。

  1. (アリス)秘密の値 a と公開する値 A を生成
  2. (アリス)公開する値 A をボブに送信
  3. (ボブ)秘密の値 b と公開する値 B を生成
  4. (ボブ)自分の秘密 b とアリスからもらった A で値 s を生成
  5. (ボブ)公開する値 B をアリスに送信
  6. (アリス)自分の秘密 a とボブからもらった B で値 s' を生成

最終的にアリスとボブはそれぞれ s' と s を得ました。ここでのポイントは以下です。

  • s' = s となるように上手いことやっている
  • s' と s の導出には秘密の値 a や b が使われているため、仮に悪意のある人が上記のやり取りを全て盗聴しても s' や s は手に入らない

上の説明では「秘密の値」「公開する値」と書きましたが、これらを「秘密鍵」「公開鍵」と呼ぶことも多いです。

なおDH鍵共有の結果(上の説明で言う s' や s)をそのまま共通鍵暗号の鍵として使うことはあまりないです。鍵を導出するための関数を用意しておき、そこへの入力として使うことが多いです。

どこで使われているか?

DH鍵共有は以下のような場面で使われています。

  • SSH通信の暗号化に使用する鍵の共有
  • TLS通信の暗号化に使用する鍵の共有
  • Wi-Fi通信の暗号化に使用する鍵の共有(Wi-Fi CERTIFIED Enhanced Openという規格の場合)

ここまでを図にすると以下のようになります。

署名

※デジタル署名と呼ばれることも多いですが、ここでは単に署名と呼びます。

続いて署名の説明をしますが、その前に、最初に説明した暗号化のことはいったん忘れてください。暗号化と署名は似ている部分もありますが、異なる技術です。署名の理解に暗号化の知識は不要ですし、混同してしまうと理解の妨げになります。「署名の中では暗号化が行われている」といった説明も見受けられますが、適切ではありません。

また、現実世界の署名(もしくは捺印)と比較しながら考えても良いとは思いますが、個人的には不要かなと思います。

署名はいくつかの機能を持っています。まずは流れから見ていきましょう。

  1. (アリス)署名鍵と検証鍵のペアを生成
  2. (アリス)検証鍵をボブに渡す
    • 署名鍵はアリスだけの秘密にする
    • ボブは検証鍵の元々の持ち主(=検証鍵とペアになる署名鍵の持ち主)を覚えておく
  3. (アリス)署名鍵を使い、メッセージに署名
    • 署名という値が生成される
    • メッセージを上書きしているわけではない
  4. (アリス)メッセージと署名をボブに送信
  5. (ボブ)検証鍵を使い、署名を検証

署名の検証に成功すると、ボブは以下のことが言えます。

  • メッセージが改竄されていない
  • 署名は、検証鍵とペアになる署名鍵で生成された

ボブは検証鍵の元々の持ち主(=検証鍵とペアになる署名鍵の持ち主)がアリスだと覚えているのでしたね。しかも署名鍵はアリスだけの秘密です。したがってボブは署名したのがアリスだと特定できます。何やら認証にも使えそうですね。

さらに、アリスは「私そんなメッセージ知らないよ」とは言えません。アリスしか知らないはずの署名鍵で署名がされているのだから当然です。これも署名の大事な性質です。

上の説明では「署名鍵」「検証鍵」と書きましたが、これらを「秘密鍵」「公開鍵」と呼ぶことも多いです。

どこで使われているか?

署名は以下のような場面で使われています。

  • SSH通信の開始時にDH鍵共有の結果が改竄されていないことの確認
  • TLS通信の開始時にDH鍵共有の結果が改竄されていないことの確認
  • SSH通信のユーザー認証やホスト認証
    • 署名を検証することで相手が本物であるかを確認
  • TLS通信のクライアント認証やサーバー認証
    • 署名を検証することで相手が本物であるかを確認
  • 公開鍵証明書
    • 署名の検証鍵(もしくは暗号化に使う公開鍵)の正当性を証明するためのもの
    • 「認証局」と呼ばれる機関が、検証鍵(公開鍵)+持ち主の情報に対して署名
    • 単に証明書と呼ばれる場合もある
    • TLSの認証でよく使われる
  • ブロックチェーンのトランザクション

SSHの公開鍵認証について知りたい方は以下を参照してください。

https://zenn.dev/tetsu1008/articles/8027cbab954e5e

なおSSHやTLSには通信内容の改竄を検知する機能もありますが、そこに署名は使われていません。

ここまでを図にすると以下のようになります。

よくある不適切な説明について

「公開鍵暗号の説明をします」と言って暗号化の説明から入り(ここまでは特に問題ない)、それを応用したのが鍵共有や署名だという説明を見かけることがあります。このような説明は、「公開鍵暗号」と言ったら「公開鍵で暗号化」のことだ、という前提になっている場合が多く、適切ではありません。

これについてはサイボウズ・ラボの光成さんの記事も参考になると思います。

https://blog.cybozu.io/entry/2021/12/28/080000

まとめ

  • 「公開鍵暗号」は公開情報と秘密情報を組み合わせて実現する「暗号化」「鍵共有」「署名」の総称
  • 「公開鍵で暗号化」はあまり使われていない

さいごに:オススメ書籍

https://gihyo.jp/book/2021/978-4-297-12307-9

  • 通称「暗認本」
  • 暗号技術全般について正しく理解したい場合はまずこれを読むべき
  • 最新の情報にもキャッチアップできる

https://www.shoeisha.co.jp/book/detail/9784798171418

  • 暗号技術全般というよりTLSについて知りたい場合はオススメ
  • TLSで使われる暗号技術については分かりやすく正確な説明があるので、いきなりこの本でも大丈夫
脚注
  1. 全く使われていないわけではありません。MicrosoftのWebブラウザーであるEdgeでは、パスワードの漏洩チェックを安全に実施するために「公開鍵で暗号化」する技術が使われています。 ↩︎

Discussion

Ken OkabeKen Okabe

やはりお前らの「公開鍵暗号」はまちがっている。
この記事を読んでまさにそう思ってしまいました。


この図はあまりよく概念整理されているとは思えませんでした。

続いて署名の説明をしますが、その前に、最初に説明した暗号化のことはいったん忘れてください。暗号化と署名は似ている部分もありますが、異なる技術です。署名の理解に暗号化の知識は不要ですし、混同してしまうと理解の妨げになります。「署名の中では暗号化が行われている」といった説明も見受けられますが、適切ではありません。

忘れるべきではなく、数学的には対になっている構造です。
似ている、異なる技術で、暗号化の知識が不要と説明するのは間違いです。適切ではありません。

こちらでわかりやすく解説しています。
https://zenn.dev/ken_okabe/articles/2024-06-22-publickey