🔑

SSL証明書の仕組みに関するメモ

2021/01/24に公開

TL;DR

  • Let's Encryptのルート証明書問題を調べていて、そもそもSSL証明書についてよく分かっていなかったので調べた
  • Zennいいなぁと思いつつROM専だったので何か書いてみたかった

自分用まとめですが、変なところあったらコメントください。

SSL証明書 is 何

デジタル証明書の一種で、暗号化通信時の身元証明に利用される。
サーバ側から「私の身元は〇〇ですよ!」とクライアント(リクエストを送信する側)に伝えるもの。
これを利用して通信をセキュアにするプロトコルがHTTPS

詳細は以下。

SSLサーバ証明書とは、Webサイトの身元の証明やSSLによる通信の暗号化に使われるデジタル証明書。
(「SSLサーバ証明書 【 SSL server certificate 】 サーバ証明書」『IT用語辞典 e-Words』より)

デジタル証明書とは、暗号化やデジタル署名に用いる公開鍵暗号の公開鍵を配送する際に、受信者が鍵の所有者を確認するために添付される一連のデータセットのこと。一般的には認証局(CA:Certificate Authority)と呼ばれる機関が発行する。
(「デジタル証明書 【 digital certificate 】 電子証明書 / electronic certificate」『IT用語辞典 e-Words』より)

電子署名とは、文書やメッセージなどのデータの真正性を証明するために付加される、短い暗号データ。作成者を証明し、改竄やすり替えが行われていないことを保証する。欧米で紙の文書に記されるサイン(signature)に似た働きをするためこのように呼ばれる。
(「電子署名 【 electronic signature 】 デジタル署名 / digital signature」『IT用語辞典 e-Words』より)

要は「通信を暗号化するための鍵が正当なものか(≒ 通信を実行する対象が発行した鍵かどうか)を証明する」ためのものがSSL証明書。

ちなみに、きちんと認証されたSSL証明書が無くても自己署名証明書(俗に言うオレオレ証明書)があれば、SSLを用いた暗号化通信自体は可能。

SSL証明書は「誰が証明(≒ 認証)する」のか

ただの一般人が構築したサーバに対し、構築した本人が「安全です!」と叫んでも信用ならない。
このサーバとの通信が信頼されるものであることを保証するのが認証局
認証の流れは以下。

  1. サーバの持ち主はCSR(Certificate Signing Request、証明書発行要求)を作成する
    • CSR には公開鍵とその所有者情報、及び申請者が対応する秘密鍵を持っていることを示すために申請者の署名が記載されている
  2. CSRを認証局に送付する
  3. 認証局は自身の秘密鍵を用いてCSRに電子署名を付与する
    • CSRをハッシュ化したものを秘密鍵で暗号化したものが電子署名になる

3で電子署名が成されたものがSSL証明書
サーバの持ち主はCSR作成時に同時に発行された秘密鍵とSSL証明書とをセットでサーバにインストールすることで、当該サーバの身元を証明する準備が完了する。

認証局には中間認証局ルート認証局がある。
中間認証局の発行する証明書が中間証明書、ルート認証局の発行する証明書がルート証明書
基本的にはそれぞれ以下の形で認証する。

  • SSL証明書(サーバ証明書):中間認証局が認証する
  • 中間証明書:ルート認証局が認証する
  • ルート証明書:ルート認証局が自身で認証する

SSL証明書の検証の流れ

  1. クライアント:サーバにHTTPS通信のリクエストを送信する
  2. サーバ:クライアントにSSL証明書(+ ルート認証局の証明書)を送信する
  3. クライアント:レスポンスからSSL証明書に署名されているルート認証局のルート証明書を取り出す
  4. クライアント:ルート証明書がWebブラウザに組み込まれているルート証明書と一致するか確認する
  5. クライアント:4で一致すれば、取り出したルート証明書からルート認証局の公開鍵を取り出し、SSL証明書の電子署名を復号化する
  6. クライアント:SSL証明書のハッシュ値を生成し、電子署名を復号化したものと一致するかを判断する
  7. クライアント:6で一致すれば、SSL証明書の公開鍵が信頼できるもの(= 身元が証明されたもの)と判断する

このあとは7で信頼した公開鍵を用い、暗号化通信を開始する。
(正確にはこの後、サーバ・クライアント双方で共通鍵を作成してから暗号化通信が始まる)

ちなみに中間認証局が間に入っている場合、2の時に中間証明書も送信する。
その上でルート認証局の公開鍵を利用し、5・6のステップを中間証明書にも適用。
これはSSL証明書以前に、その認証をした中間認証局が信頼できるものかを判断するため。

まとめ

分かった感がある。

その他補足

中間証明書が必要な理由

  1. セキュリティ強化のため
    • 中間証明書を挟むことで、ルート証明書への直接的な攻撃を防げる
  2. 運用を楽にするため
    • 中間証明書を発行せずに2段階構造にしていると、ルート証明書を失効した際に証明書全体が無効になる
    • 中間証明書で3階層以上の構造にしておけば、脆弱性をつかれて情報が漏洩した場合もルート証明書まで失効することが無い

結局Let's Enceyptのルート証明書問題が何故起こるか

  1. Let's Encryptがお世話になっていたルート証明書の期限が切れる
  2. 多くのAndroid端末のアップデートが切れている(ため、ルート証明書を更新できない)

Let's Encryptは当初、普及率の問題から、IdenTrustのルート証明書(DST Root CA X3)経由で独自のルート証明書(ISRG Root X1)を利用していた。
ここではクロスルート証明書の仕組みを利用している。

クロスルート証明書は「本来端末に入っていないルート証明書Bを、端末に入っているルート証明書Aに認証してもらい、端末にルート証明書Bを利用してもらう」という仕組み。
要はクライアントの端末に入っていないルート証明書を使えるようにするもの。
このためLet's Encryptの利用するクロスルート証明書には、上記のDST Root CA X3とISRG Root X1の2つ鍵を使った署名が成されている。
つまりは、端末の知らないISRG Root X1をDST Root CA X3が保証してくれている。

しかし間もなくDST Root CA X3が失効する。失効すると、ISRG Root X1を保証する手立てがなくなる。
ISRG Root X1を保証するためのクロスルート証明書なのに、それを保証する証明書が使えなくなってしまうから。

加えてAndroid端末の多くにISRG Root X1がインストールされていない + アップデートができないという状況のため、DST Root CA X3が失効した時点でLet's Encryptの証明書を利用した通信ができなくなる、という状況。

参考資料

Discussion