1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

証明書チェーンを図解する

1
Posted at

この記事は riku-kobayashi.jpに掲載した記事の転載です。

前回の記事で、TLSハンドシェイクの途中でサーバーが証明書を送ってきて、クライアントがそれを検証すると書きました。今回はその検証の中身、証明書チェーンの仕組みを図解します。

初めてアクセスするサーバーなのに、ブラウザはこのサーバーは本物だとどうやって判断しているのか、という話です。

前提: 公開鍵暗号を署名に使う

証明書チェーンは、公開鍵暗号を暗号化ではなく署名に使う話の上に成り立っています。暗号化と署名で鍵の使う向きが逆になる、という話は前の記事で図解したので、ここでは結論だけ振り返ります。

自分の秘密鍵で署名すると、誰でもその公開鍵で検証できます。秘密鍵を持っている本人にしか署名は作れないので、検証できれば本人が作ったデータであることの証拠になります。

証明書とは、公開鍵・発行先の情報(ドメイン名など)・有効期限をひとまとめにしたデータに、発行者が自分の秘密鍵で署名を付けたものです。この公開鍵は確かにこのドメインのものだと、発行者が保証しているという意味になります。

証明書チェーンの構造

証明書は1枚だけでなく、複数の証明書が連なったチェーンになっています。

  • サーバー証明書(リーフ証明書): 実際にサイトが提示する証明書。公開鍵とドメイン名が入っています
  • 中間証明書: サーバー証明書に署名した認証局(中間CA)の証明書
  • ルート証明書: 中間証明書に署名した、チェーンの最上位にある認証局(ルートCA)の証明書。発行者と所有者が同じ自己署名証明書です

サーバー証明書だけでなく中間証明書を挟むのには理由があります。ルートCAの秘密鍵はチェーン全体の信頼の起点なので、オフラインの厳重な環境で保管され、日々の証明書発行には使われません。実際の発行業務は中間CAが行い、万が一中間CAの鍵が漏洩・悪用されても、その中間証明書だけを失効させればルート証明書自体を失効させずに被害を止められます。

証明書を発行するとは

ここまでは署名されているという結果だけを見てきましたが、その署名は具体的にどうやって手に入れるのか、という話です。

まず、証明書を発行してほしい側(サーバー運用者)が秘密鍵と公開鍵のペアを自分で生成します。秘密鍵は誰にも渡さず、公開鍵と発行してほしいドメイン名などの情報をまとめたCSR(Certificate Signing Request、証明書署名要求)を作り、これを中間CAに送ります。

CAが確認するのは、CSRに書かれた公開鍵の中身ではなくこのドメインを本当に管理しているかです。この確認の厳しさによって証明書の種類が分かれます。

  • DV(Domain Validation): ドメインの管理権限があるかだけを確認。指定されたDNS TXTレコードを追加する、指定されたファイルをWebサーバーに置く、といった方法で証明できれば発行される
  • OV(Organization Validation): DVに加えて、運営組織が法人登記などで実在するかを確認
  • EV(Extended Validation): OVよりさらに厳格な審査。以前はブラウザのアドレスバーが緑色になるなど表示上の特典がありましたが、Chromeは2019年のバージョン77でこの表示を廃止し、Firefoxも同年のバージョン70で追随したため、今は見た目上の差はほぼありません1

DVの確認が取れると、CAは中間CAの秘密鍵でCSRの公開鍵とドメイン情報に署名し、サーバー証明書として発行します。ここでようやく、最初の章で説明した秘密鍵で署名すれば誰でも公開鍵で検証できるの構造ができあがります。

このDV確認、手作業でやるとかなり面倒なんですが、今はほぼ自動化されています。ACME(Automatic Certificate Management Environment)というプロトコルがあり、Let's EncryptなどのCAはこれに対応しています。certbotのようなクライアントがCSR生成・DNS/HTTPでの所有権確認・証明書取得までを自動でやってくれるので、実際に手でCSRを書く機会は今はほとんどありません。

検証の流れ

クライアント(ブラウザ)は受け取ったサーバー証明書から、発行者をたどってルート証明書まで遡りながら検証します。

具体的には次の4点を確認しています。

  1. 署名の連鎖: サーバー証明書の署名を中間証明書の公開鍵で検証 → 中間証明書の署名をルート証明書の公開鍵で検証、と1段ずつ遡る
  2. 信頼の起点: 最終的にたどり着いたルート証明書が、OSやブラウザに事前installされたトラストストア2に含まれているか
  3. ホスト名の一致: アクセスしているドメイン名が、サーバー証明書のSAN(Subject Alternative Name)に含まれているか3
  4. 有効期限・失効状態: 期限内か、失効していないか(後述)

どれか1つでも欠けると、ブラウザは警告を出します。「オレオレ証明書」(自己署名証明書)で警告が出るのは、2番目のルートCAをたどれない、つまり信頼の起点にたどり着けないためです。

ルート証明書はなぜ最初から信頼されているのか

トラストストアに入っているルート証明書は、OSやブラウザのベンダー(Apple、Google、Microsoft、Mozillaなど)が独自に審査した認証局のものだけです。それぞれルートプログラムと呼ばれる審査基準を持っていて、運用体制やセキュリティ監査(WebTrust監査など)をクリアした認証局だけがルート証明書を組み込んでもらえます。

つまり初対面のサーバーを信頼できるように見えるのは、実際にはOS/ブラウザベンダーが事前に審査したCAを信頼しているからです。信頼の起点はネットワークの外、OSやブラウザのアップデートという形で配布されています。

ルート証明書が入れ替わることもある

ルート証明書にも有効期限があり、暗号アルゴリズムの強度が古くなれば新しいものに置き換わります。OSやブラウザのアップデートに古いルート証明書の失効・新しいルート証明書の追加が含まれているのはこのためです。

失効の仕組み

証明書は有効期限内でも、秘密鍵の漏洩などがあれば無効にする必要があります。この失効確認には主に2つの方式があります。

CRL OCSP
正式名称 Certificate Revocation List Online Certificate Status Protocol
方式 失効した証明書の一覧をCAが配布 個別の証明書についてCAにリアルタイムで問い合わせ
弱点 リストが巨大になりがち、更新間隔がある 問い合わせのたびに通信が発生し遅い。CAにアクセス履歴が残る

OCSPの弱点を解消するため、OCSPステープリングという仕組みもよく使われます。サーバー自身が事前にCAへOCSP問い合わせを行い、署名付きの結果を証明書と一緒にクライアントへ提示(ステープル=ホチキス留め)する方式です。クライアントがCAに直接問い合わせる必要がなくなり、速度とプライバシーの両方が改善します。


ハンドシェイクの1-RTTで済む鍵交換の裏で、サーバーの身元はこうした署名の連鎖で保証されている、という話でした。

参照

  1. Googleは「EV UIはユーザーが期待するほどの保護になっていない」という調査結果を理由に、Chrome 77(2019年)でアドレスバーの組織名表示を廃止しました。Firefoxも同年のFirefox 70で追随しています。 ↩

  2. OSやブラウザに事前に組み込まれた、信頼済みルート証明書の一覧のことです。 ↩

  3. 古い証明書ではCommon Name(CN)というフィールドでホスト名を照合していましたが、1つの証明書で複数ドメインをカバーできないなどの制約があり、現在の主要ブラウザはSANのみを見てCNは無視します。 ↩

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?