【証明書入門 第5回】PKIと信頼の仕組み ― 証明書チェーン・信頼ストア・失効・CT・CAA

証明書・PKI
スポンサーリンク
スポンサーリンク

「ブラウザーでは開けるのに、監視ツールのHTTPSチェックだけ失敗するんです」
「社内CAの証明書、Windowsでは大丈夫なのにLinuxのサーバーから呼ぶとエラーになります」

どちらも、証明書そのものは正しいのに起きるトラブルです。原因は、証明書を「誰が、どこまでさかのぼって信頼しているか」、つまりPKI(公開鍵基盤)と信頼の仕組みにあります。

第4回では、証明書1枚の中身を読みました。第5回では視点を広げて、証明書どうしのつながり(チェーン)、何を信頼の起点にするか(信頼ストア)、そして失効・CT・CAAといった、信頼を保つための仕組みを見ていきます。


CA・RA・VAの役割

PKI(Public Key Infrastructure、公開鍵基盤)は、公開鍵とその持ち主の結び付きを第三者が保証し、誰でも確かめられるようにする仕組み全体です。中心は認証局(CA)で、内部は役割で分けて考えます。

申請者がCAのRA(登録局)に申請して審査を受け、IA(発行局)がCAの秘密鍵で署名して発行し、VA(検証局)がCRL・OCSPで失効の状態を公開することと、サイトを開くときCAは関与しないことを示す図
  • RA(登録局):申請を受けて審査する窓口。ドメインを管理していること(DV)や組織の実在(OV・EV)を確かめる
  • IA(発行局):審査を通った申請にCAの秘密鍵で署名し、証明書を発行する
  • VA(検証局):証明書が失効していないかを、CRLやOCSPで公開する

公開CAではこれらを分けて監査を受けながら運用し、社内CA(AD CSなど)では1台で兼ねることが多くなります。

なお、サイトを開くたびにCAが関与するわけではなく、CAが止まっても通信は続きます。ただし、CRLの更新が止まると検証に失敗する製品があります。発行までがRA・IA、発行した後の見張りがVA、と覚えておきましょう。


ルートCA・中間CA・サーバー証明書

CAは親子の階層を作れます。

端末の信頼ストアにあらかじめ入っているルートCA(自己署名、鍵はオフラインのHSM)が中間CAに署名し、中間CAがサーバー証明書に署名し、検証は下から上へたどることを示す図
  • 最上位のルートCAの証明書は、自分で自分に署名した自己署名証明書で、OSやブラウザーの信頼ストアにあらかじめ入っている
  • ルートCAは中間CAの証明書に署名し、中間CAが利用者のサーバー証明書に署名する
  • 検証する側はサーバー証明書から発行者を順にたどり、信頼ストアにあるルートに行き着けば信頼する

これが証明書チェーン(信頼の連鎖)です。チェーンのどこか1つでも切れたら、全体が信頼されません。

中間CAを置くのは、ルートCAの秘密鍵を守るためです。ルートの鍵が漏れると、そのルートを信頼するすべての端末に影響し、入れ替えには信頼ストアの更新で何年もかかります。そこでルートの鍵はHSM(鍵を守る専用装置)に入れてオフラインで保管し、中間CAに署名するときだけ使います。日々の発行は中間CAが行い、問題があれば中間CAだけを失効させて作り直せます。


中間証明書はサーバーが送る

冒頭の「ブラウザーでは開けるのに、監視ツールだけ失敗する」の答えがここです。

正しい設定ではサーバーがサーバー証明書と中間証明書を送り端末の信頼ストアのルートとつながるが、中間証明書を入れ忘れるとChrome・WindowsはAIAから取得し、Firefoxは手持ちで補う一方、curl・Java・アプリ・機器は補わずerror 21で失敗することを示す図

TLSのハンドシェイクでは、サーバーが自分の証明書と中間証明書をまとめて送り、クライアントはそれを手元の信頼ストアのルートにつなげます。信頼ストアにあるのはルートだけなので、サーバーが中間証明書を送らないと、チェーンが途切れます。

厄介なのは、症状が端末によって違うことです。

  • WindowsやChrome:証明書のAIA(第4回)から中間証明書を取りに行く
  • Firefox:公開CAの中間証明書をあらかじめ持っている
  • openssl、curl、Java、多くのスマホアプリや組み込み機器:補わない

そのため、「ブラウザーでは開けるのに、システム連携や監視だけが失敗する」という形で現れます。サーバーには、自分の証明書、中間証明書の順に連結したファイル(fullchain)を設定します。ルートは送らなくてかまいません。

ブラウザーで開けても、入れ忘れがないとは言えません。確かめるときは、補わないopensslやcurlを使います。


チェーンを確かめる

$ openssl verify -show_chain -CAfile root.crt -untrusted inter.crt server.crt
server.crt: OK
Chain:
depth=0: C=JP, ST=Tokyo, L=Chiyoda-ku, O=Example Corp., CN=www.example.jp (untrusted)
depth=1: C=JP, O=Example CA Inc., CN=Example Issuing CA E1 (untrusted)
depth=2: C=JP, O=Example CA Inc., CN=Example Root CA R1

$ openssl verify -CAfile root.crt server.crt           # 中間証明書を渡さない
C=JP, ST=Tokyo, L=Chiyoda-ku, O=Example Corp., CN=www.example.jp
error 20 at 0 depth lookup: unable to get local issuer certificate
error server.crt: verification failed
PS> certutil -verify -urlfetch server.crt
  • -CAfileは信頼するルート、-untrustedは途中の中間証明書。depth=0がサーバー証明書で、数字が大きいほどルートに近い
  • error 20は「発行者の証明書が見つからない」=中間証明書の不足。サーバーならfullchainの作り忘れを疑う
  • Windowsのcertutil -verify -urlfetchは、AIAから中間証明書を、CDPからCRLを取得して、チェーンと失効をまとめて確かめる

信頼ストア

冒頭の2つ目、「Windowsでは大丈夫なのにLinuxではエラー」の答えは、信頼ストアが製品ごとに別々だということです。

信頼ストア使う製品決めるところ社内CAのルートを入れる方法
MicrosoftWindows、IIS、.NET、EdgeMicrosoft Trusted Root ProgramGPO で「信頼されたルート証明機関」に配布
ApplemacOS、iOS、SafariApple Root Certificate Program構成プロファイル(MDM)
Mozilla NSSFirefox、ThunderbirdMozilla Root Store PolicyFirefox は OS に追加したルートも読む(Windows・macOS)
Chrome Root StoreChrome(iOS 版を除く)Chrome Root ProgramOS のストアに入れれば Chrome も使う
Java(cacerts)Java アプリ、Tomcat 等JDK の配布元keytool -importcert -cacerts
Linux(ca-certificates)curl、openssl、Python 等ディストリビューション(元は Mozilla)update-ca-certificates(RHEL 系は update-ca-trust)

社内CAのルートをGPOでWindowsに配っただけでは、LinuxのサーバーやJavaアプリ、コンテナーの中では信頼されません。それぞれの信頼ストアに入れる必要があります。

ChromeはChrome 105から独自のChrome Root Storeへの切り替えを始め(Windows・macOSはChrome 108で既定)、公開CAの信頼はOSに依存しなくなりました(Edgeも112から内蔵の検証器)。また、WindowsはルートをWindows Updateから必要な時に取るため、閉じたネットワークのサーバーでは足りないことがあります。


ルートプログラムとCA/Browser Forum

では、信頼ストアに入れるCAは、誰がどう決めているのでしょうか。

Microsoft・Apple・Mozilla・Chromeのルートプログラムと公開CAがCA/Browser Forumに参加・投票してBRを定め、公開CAは毎年WebTrust・ETSIの監査を受けて結果をCCADBで公開し、ルートプログラムが信頼ストアへの採用・除外を決めることを示す図
  • どのCAのルートを信頼ストアに入れるかは、OSやブラウザーの各社がルートプログラムで決める
  • 共通の土台は、CAとブラウザー各社が参加するCA/Browser ForumのBaseline Requirements(BR)。ドメインの確認方法、証明書の項目、有効期間、失効までの期限などが決められ、改定は投票(Ballot。例:有効期間を短縮したSC-081、第6回)で行う
  • CAはWebTrustやETSIの監査を毎年受け、結果をCCADBで公開する
  • ルートプログラムは独自の要件も加える。たとえばChromeは、鍵の生成から15年を超えたルートを外すこと、階層をサーバー認証専用にすること、2027年3月15日から自動発行(第8回)に対応することを求める

BRが物差し、監査が採点、ルートプログラムが合否を決める、という関係です。基準を守れないCAは信頼ストアから外されます(後で実例を紹介します)。


検証の手順

クライアントは、証明書を受け取ると次の順に確かめます。

チェーン、署名、有効期間、名前、用途、CAの制約、失効、CTの8つの関門を順に通り、それぞれで失敗したときのエラーの例と、openssl verifyは名前・用途・失効をオプションなしでは確かめないことを示す図
順確かめること見る項目失敗の例(ブラウザー/openssl)
1チェーンを組み、信頼ストアのルートに届くかIssuer・Subject、AKI・SKI、AIAERR_CERT_AUTHORITY_INVALID/error 20
2各証明書の署名が正しいか署名値、発行者の公開鍵署名の不正、SHA-1 などの弱い署名
3有効期間の内かNot Before・Not AfterERR_CERT_DATE_INVALID(端末の時刻のずれでも起きる)
4名前が一致するかSANERR_CERT_COMMON_NAME_INVALID/error 62
5用途が合っているかKey Usage、EKUunsuitable certificate purpose(error 26)
6途中の証明書が CA で、制約を守っているかBasic Constraints、Name Constraints中間が CA:FALSE、許されない名前
7失効していないかCRL、OCSP、CRLSets・CRLiteERR_CERT_REVOKED/error 23
8CT の要件を満たすかSCTERR_CERTIFICATE_TRANSPARENCY_REQUIRED

注意したいのは、opensslのverifyは名前(-verify_hostname)、用途(-purpose)、失効(-crl_check)を、指定しないと確かめないことです。「opensslでOK」はブラウザーでOKとは限りません。ブラウザーのエラーの詳細に出るコードから、どの段階で失敗したかが分かります(第10回)。


失効の仕組み:CRLとOCSP

秘密鍵が漏れた、誤って発行した、サーバーを廃止した、といった理由で、有効期間の途中で証明書を無効にすることを失効といいます。CAは失効させた証明書のシリアル番号を公開し、検証する側はそれを確かめます。

CRLではCAが定期公開する失効の一覧を配布サーバーから取得して手元で照合し、OCSPではクライアントがOCSPレスポンダーに1枚ずつ問い合わせるため、CA側にどの端末がどのサイトを開いたかの記録が残ることを示す図
  • CRL(証明書失効リスト):失効したシリアル番号の一覧にCAが署名して、定期的に公開するファイル。URLは証明書のCDPに書かれている。一覧をまとめて取るので閲覧先はCAに伝わらないが、大きくなりがち
  • OCSP:証明書1枚ごとに、有効かどうかをCAのOCSPレスポンダーに問い合わせる方式。URLはAIAに書かれている。応答は小さいが、接続のたびに問い合わせるので遅く、どのサイトを開こうとしているかがCAに分かるという問題があった

失効の確かめ方の比較

方式仕組み利点課題・現状
CRLCA が失効の一覧を公開し、クライアントが取得閲覧先が漏れない一覧が大きい。公開CAは2024年3月から公開が必須
OCSPクライアントが1枚ずつ CA に問い合わせ応答が小さい遅い、閲覧先が漏れる。公開CAでは任意になった
OCSP ステープリングサーバーが OCSP の応答を取っておき、TLS の中で渡すクライアントの問い合わせが不要サーバーの設定が必要。OCSP の終了で役目を終えつつある
CRLSets(Chrome)Google が重要な失効を選んでまとめ、Chrome に配る速い、閲覧先が漏れないすべての失効は含まない
CRLite(Firefox)公開証明書の失効情報を圧縮して配る全件を手元で判定できるFirefox 137 からデスクトップで有効。142 で DV 証明書の OCSP を停止

どの方式でも、ブラウザーは接続のたびにCAへ問い合わせない方向に進んでいます。opensslやcurlは既定では失効を確かめません。社内のWindows環境では、CryptoAPIがCDPからCRLを取得して確かめるため、社内CAのCRLの配布先に端末から届くことが前提になります(第9回)。


OCSPは任意・CRLは必須へ

失効の仕組みは、ここ数年で大きく変わりました。

  • 2023年8月、CA/Browser ForumがBallot SC-063を可決。2024年3月15日から、公開CAはCRLの公開が必須、OCSPは任意になった
  • 失効情報を持たなくてよい短期証明書も定義された(2026年3月15日以降の発行分は有効期間7日以内)
  • Let’s EncryptはOCSPを終了:2025年5月7日に証明書からOCSPのURLを外してCRLのURLを入れ、2025年8月6日にOCSPレスポンダーを停止した

テスト用の中間CAで証明書を失効させ、CRLで確かめると次のようになります(抜粋)。

$ openssl crl -in ica-e1.crl -noout -text
        Last Update: Sep 26 01:02:52 2026 GMT
        Next Update: Oct  3 01:02:52 2026 GMT
Revoked Certificates:
    Serial Number: 61AEBAE25C18E503B7D26AD887492683DD3C00E5
        Revocation Date: Sep 26 01:02:52 2026 GMT
        CRL entry extensions:
            X509v3 CRL Reason Code:
                Key Compromise

$ openssl verify -crl_check -CAfile cafile.pem -CRLfile ica-e1.crl server.crt
error 23 at 0 depth lookup: certificate revoked

OCSPのための通信の許可やステープリングの設定は、不要になりつつあります。逆に社内CAでは、CRLの公開と更新を止めないことが重要です。Next Updateを過ぎたCRLは、検証の失敗につながります。


Certificate Transparency

CAが誤って、あるいは攻撃を受けて、他人のドメインの証明書を発行する事故は何度も起きました(後で紹介します)。

CAがプレ証明書をCTログに送って受付の証拠SCTを受け取り、SCT入りの証明書をサーバーがTLSで提示し、ブラウザーがSCTが足りているかを確かめ、ドメインの持ち主はcrt.sh等で身に覚えのない発行がないか検索できることを示す図

Certificate Transparency(CT、証明書の透明性)は、公開CAが発行するすべての証明書を、誰でも読める追記専用のCTログに記録させ、不正な発行を後から見つけられるようにする仕組みです(RFC 6962)。

  1. CAは発行前に、証明書の下書き(プレ証明書)をログに送る
  2. 受付の証拠となる署名付きのタイムスタンプ(SCT)を受け取り、証明書に埋め込む(第4回)
  3. ブラウザーは、SCTが足りない証明書を拒否する

Chromeは2018年4月30日より後の発行分に、Appleは2018年10月から、FirefoxはFirefox 135(2025年)からCTを求めています。

CTは不正な発行を防ぐのではなく、隠せなくする仕組みです。見つけるのは、ドメインの持ち主の役目です。


crt.shで自社ドメインを監視する

CTログは、crt.shという無料の検索サービスで誰でも調べられます。

$ curl -s "https://crt.sh/?q=example.com&output=json&exclude=expired" \
    | jq -r '.[] | [.not_before, .issuer_name, .name_value] | @tsv'
2026-09-24T00:00:00  C=GB, O=Sectigo Limited, CN=Sectigo Public Server Authentication CA DV E36  *.example.com\nexample.com
2026-07-29T22:10:08  C=US, O=SSL Corporation, CN=Cloudflare TLS Issuing ECC CA 3  *.example.com\nexample.com
2026-07-29T22:10:08  C=US, O=SSL Corporation, CN=Cloudflare TLS Issuing ECC CA 3  *.example.com\nexample.com
PS> Invoke-RestMethod "https://crt.sh/?q=example.com&output=json&exclude=expired" |
      Select-Object not_before, issuer_name, name_value

(2026年9月26日に実行した結果の抜粋)

  • 同じ証明書が2行ずつ出るのは、プレ証明書と本証明書の両方がログに残るため
  • 見るべきは発行者(issuer_name)。契約していないCA、使っていないはずのCAがあれば調べる。サブドメインまで含めるならq=%.example.jp
  • 定期的に取得して差分を通知する、CTの監視サービスを使う、などで仕組みにする。crt.shは混んでいると応答しないことがある

注意:CTログは誰でも見られます。社内用のホスト名を公開CAの証明書に入れると、外部から見えます。


CAA:発行してよいCAを宣言する

CTが「発行後に見つける」仕組みなら、CAAは「発行前に止める」仕組みです。

example.jp. 3600 IN CAA 0 issue "letsencrypt.org; accounturi=https://acme-v02.api.letsencrypt.org/acme/acct/123456789"
example.jp. 3600 IN CAA 0 issue "amazon.com"
example.jp. 3600 IN CAA 0 issuewild ";"
example.jp. 3600 IN CAA 0 iodef "mailto:security@example.jp"
  • CAA(RFC 8659)は、そのドメインの証明書を発行してよいCAをDNSで宣言するレコード。書き方と探し方は、連載「DNS入門」の第6回で扱った
  • CAは発行の前にCAAを確かめる義務がある(2017年9月から)。2026年3月15日からは、DNSSECで署名されたドメインではCAがDNSSECの検証も行い、検証エラーを発行の許可とみなさない
  • accounturi(RFC 8657)で、CAの中のアカウントまで絞れる(上の1行目)。BRでは2027年3月15日からCAがこの指定を守る義務を負う(それまでは推奨)

CTとCAAは両方を組み合わせます。なお、CAを変える、ACMを使い始めるといったときにCAAを直し忘れると、発行や自動更新が失敗します(第8回)。


CAが信頼を失った実例

最後に、ルートプログラムが実際にCAを外した例です。

年CA何が起きたか結果
2011DigiNotar(オランダ)侵入され、*.google.com を含む500枚以上の不正な証明書を発行。イランでの通信の傍受に使われた各ブラウザー・OS が不信任。同年9月に破産
2017〜2018Symantec(VeriSign・Thawte・GeoTrust・RapidSSL を含む)長年にわたる不適切な発行と、外部の発行者への監督の不備Chrome 66 で2016年6月より前の発行分、Chrome 70 で残りを不信任。事業は DigiCert へ
2022〜2023TrustCorスパイウェアを作る企業との関係が報じられたMozilla・Microsoft が不信任、Chrome 111 でルートを削除
2024Entrust誤発行とその報告・改善の不備が続いたChrome 131(2024年11月12日)から新しい発行分を不信任。Apple・Mozilla も続いた。事業は2025年に Sectigo へ
2025Chunghwa Telecom(台湾)、Netlock(ハンガリー)基準違反と、改善の約束の不履行が続いたChrome 139 から、2025年7月31日より後の発行分を不信任

最近は、発行済みの証明書は期限まで使わせ、SCTの日付で新しい発行分だけを拒否する形が主流です。自社の証明書のCAが対象になったら、期限前に別のCAへ移ります。「大手のCAだから安心」とは限らない、ということが分かります。


考えてみよう

  1. 社内CAのルート証明書は、どの信頼ストアに入っていますか。Windowsの端末だけでなく、Firefox、Javaアプリ、Linuxのサーバー、コンテナーの中でも信頼されていますか。
  2. 「ブラウザーでは開けるのに、監視ツールのHTTPSチェックだけが失敗する」と報告を受けました。何を疑い、どのコマンドで確かめますか。
  3. 自社ドメインをcrt.shで検索してください。発行者の一覧に心当たりのないCAや、知らないホスト名はありませんか。CAAは設定されていますか。

ヒント:この記事の「信頼ストア」、「中間証明書」とerror 20・21、「CT」と「CAA」が手がかりです。


まとめ

  • CAはRAが審査、IAが発行、VAが失効を公開。通信のたびにはCAは関与しない
  • ルート→中間→サーバーの順に署名し、検証は逆にたどる。ルートの鍵はオフラインで守る
  • 中間証明書はサーバーが送る。ブラウザーは補っても、curl・Java・機器は補わない
  • 信頼ストアは製品ごとに別々。社内CAのルートはそれぞれに入れる
  • 公開CAではCRLが必須、OCSPは任意に。社内CAはCRLの更新を止めない
  • CTは発行後に見つけ、CAAは発行前に止める。両方を組み合わせる

次回は、DV・OV・EVなどの証明書の種類と、CSRの作成からドメインの確認、発行までの流れを扱います。


連載「証明書入門」全11回

  1. なぜ証明書が必要か
  2. 暗号の基礎
  3. openssl・PowerShellで試す
  4. X.509証明書の中身
  5. PKIと信頼の仕組み(この記事)
  6. 証明書の種類と発行
  7. TLSの仕組み
  8. ライフサイクルと自動化
  9. 社内PKIとクラウド
  10. 証明書トラブルシュート
  11. 証明書の設計演習

コメント

タイトルとURLをコピーしました