TLS の記事では、サーバが本物かどうかを、証明書が「信頼する CA までつながるか」で確かめました。では、その CA とは何で、つながりはどう作られ、使えなくなった証明書はどう止めるのか。この記事では、証明書のしくみ全体である PKI(公開鍵基盤)を、RFC と Microsoft のドキュメントで確かめながら、テスト用の環境で OpenSSL を使ってルート CA から実際に作り、失効まで動かした結果と一緒に一歩ずつ図にしました。
- PKI は「信頼できる発行元(CA)が、名前と公開鍵の組み合わせを保証する」しくみ
- 証明書の中身(発行者・主体・有効期間・公開鍵・拡張・CA の署名)
- ルート・中間・サーバの証明書チェーンと、クライアントが確かめること
- 失効のしくみ(CRL と OCSP)と、有効期間の短縮・更新の自動化
- OpenSSL で CA を作り、発行・検証・失効を実際に試す方法
まずはたとえで:パスポート
海外に行くとき、パスポートを見せて入国審査を受けます。パスポートは国が発行したもので、名前・写真・番号・有効期限が書かれ、国の印が押されています。入国審査では、信じている国の印か、期限内か、写真の本人か、無効になったパスポートのリストに載っていないかを確かめます。
PKI(Public Key Infrastructure、公開鍵基盤)は、これをデジタルの世界で行うしくみです。国にあたるのが CA(Certificate Authority、認証局)、パスポートにあたるのが証明書、写真にあたるのが公開鍵です。RFC 5280 は、公開鍵と持ち主の結びつきを、信頼される CA が証明書に署名することで示す、と説明しています。どの CA を信じるかは、パスポートと同じく、確かめる側があらかじめ決めておきます。
使う場面
証明書は TLS のサーバ証明書だけでなく、いろいろな場面で使われています。Microsoft の AD CS(Active Directory 証明書サービス)のドキュメントも、証明書の確認ができないと、VPN の接続、スマートカードでのサインイン、メールの署名の確認などが失敗すると書いています。
このシリーズでは、SAML のアサーションの署名を証明書で確かめる話も出てきました。次の記事で扱う mTLS では、クライアントも証明書で自分を示します。どれも、ここで見る PKI のしくみの上に乗っています。
PKI の基本の形
証明書の中身
証明書の形式は X.509 で、インターネットで使う形は RFC 5280 で決まっています。証明書は「署名される中身(tbsCertificate)」「署名のアルゴリズム」「署名の値」の3つでできています。中身には、シリアル番号、発行者、有効期間、主体(持ち主)、公開鍵と、v3 で加わった拡張が入ります。図は、この記事の STEP 3 で実際に発行したサーバ証明書の値です。
| 拡張 | 意味 |
|---|---|
| 基本制約(basicConstraints) | CA:TRUE なら CA の証明書。CA:FALSE の証明書の公開鍵で、ほかの証明書の署名を確かめてはいけない。pathlen は、この後に続いてよい中間 CA の数 |
| 鍵の用途(keyUsage) | CA なら証明書への署名(keyCertSign)と CRL への署名(cRLSign)。サーバ証明書なら署名(digitalSignature)など |
| 拡張鍵用途(EKU) | サーバ認証(serverAuth)、クライアント認証(clientAuth)など、何に使う証明書か |
| SAN(subjectAltName) | 持ち主の名前。TLS では接続先の名前と比べる |
| CRL 配布点(CDP) | 失効リスト(CRL)を取りに行く場所 |
| AIA | 発行した CA の証明書の場所や、OCSP(失効の問い合わせ先)の場所 |
証明書チェーン:ルート・中間・サーバ
多くの PKI では、CA を2階層以上に分けます。いちばん上のルート CA は、自分で自分に署名した証明書(自己署名証明書)を持ちます。RFC 5280 は、自己署名証明書が「証明書のつながりを始めるための公開鍵」を伝えるために使われる、としています。ルート CA は中間 CA(発行 CA)の証明書に署名し、中間 CA がサーバなどの証明書を発行します。
ルートの秘密鍵が漏れると、その下のすべての証明書が信頼できなくなります。そのため Microsoft は、本番の AD CS では、スタンドアロンのルート CA で発行 CA に署名したら、ルート CA をオフラインにすることを推奨しています。ふだんの発行は中間 CA が行い、ルートは中間 CA の証明書を作り直すときなどにだけ使います。
ルート証明書が本物かどうかは、証明書だけでは確かめられません。自己署名なので、だれでも同じ名前のルート証明書を作れるからです。Microsoft の Cloud PKI の説明も、ルート証明書を信頼するには、信頼済みのルートストアに入れるしかない、としています。OS やブラウザには、あらかじめ公的な CA のルート証明書が入っていて、社内の CA なら、管理者が社内の PC に配ります。
誰が何を持つか
秘密鍵は、ルート CA・中間 CA・サーバの3か所にあります。どれも持ち主の外に出してはいけませんが、漏れたときの影響が大きいのはルート、次に中間です。相手に渡すのは、いつも公開鍵の入った証明書だけです。
全体の流れ
準備:CA の階層を作る
まず、ルート CA と中間 CA を作り、ルート証明書をクライアントに配ります。
| 手順 | 誰が・どこで | 何をするか | 鍵(物)はどうなるか・使う鍵 |
|---|---|---|---|
| ① | 管理者・ルート CA で操作 | 鍵ペアと自己署名の証明書を作る | ルートの秘密鍵はルート CA の中だけ。証明書は CA:TRUE |
| ② | ルート CA → クライアント | ルート証明書を配る | クライアントの信頼済みストアに入る(信頼の起点) |
| ③ | 管理者・中間 CA で操作 | 鍵ペアと CSR を作る | 中間の秘密鍵は中間 CA の中だけ |
| ④ | 中間 CA → ルート CA | CSR を渡す | ルートがオフラインなら、ファイルで運ぶ |
| ⑤ | ルート CA | 確かめて署名する | ルートの秘密鍵で署名。CA:TRUE, pathlen:0 を付ける |
| ⑥ | ルート CA → 中間 CA | 中間証明書を渡す | 中間 CA が「ルートに認められた CA」になる |
| ⑦ | ルート CA | オフラインにする | ルートの秘密鍵をふだんは使わない |
| ⑧ | 管理者・中間 CA で操作 | CRL 配布点と AIA を決める | 発行する証明書に入る。あとで変えても、発行済みの証明書は古いまま |
| ⑨ | 中間 CA | 発行の準備ができる | 中間の秘密鍵で証明書と CRL に署名できる |
CSR(Certificate Signing Request、証明書の申請書)は PKCS #10(RFC 2986)で決まっていて、名前と公開鍵などを入れ、申請者自身の秘密鍵で署名したものです。秘密鍵そのものは入っていません。⑧について Microsoft は、CA を作ったら、証明書を発行する前に AIA と CDP を決めるよう勧めています。URL を変えても、変える前に発行した証明書は古い場所を指したままだからです。
発行と利用:サーバ証明書を発行して使う
準備ができたら、サーバの証明書を発行し、クライアントがそれを確かめるところまでを見ます。
| 手順 | 誰が・どこで | 何をするか | 鍵(物)はどうなるか・使う鍵 |
|---|---|---|---|
| ⑩ | サーバで操作 | 鍵ペアを作る | サーバの秘密鍵はサーバの中だけ |
| ⑪ | サーバで操作 | CSR を作る | 名前(SAN)と公開鍵を入れ、サーバの秘密鍵で署名 |
| ⑫ | サーバ → 中間 CA | CSR を送る | 秘密鍵は送らない |
| ⑬ | 中間 CA | 申請を確かめる | その名前を使ってよい相手か。公的 CA はドメインの管理を確かめる |
| ⑭ | 中間 CA | 署名して発行する | 中間の秘密鍵で署名。シリアル番号と状態を記録する |
| ⑮ | 中間 CA → サーバ | サーバ証明書を渡す | 証明書は公開の情報 |
| ⑯ | サーバで操作 | 証明書と中間証明書を設定する | 秘密鍵と証明書の組み合わせを設定する |
| ⑰ | クライアント → サーバ | TLS で接続する | ― |
| ⑱ | サーバ → クライアント | サーバ証明書と中間証明書を送る | ルート証明書は送らない(クライアントが持っている) |
| ⑲ | クライアント | チェーンをたどる | 中間の公開鍵でサーバ証明書の署名を、ルートの公開鍵で中間証明書の署名を確かめる |
| ⑳ | クライアント → 失効情報 | 失効を確かめる | CRL 配布点から CRL を取るか、OCSP で聞く |
| ㉑ | 失効情報 → クライアント | 失効していないと答える | CRL も OCSP の応答も、CA などの署名つき |
| ㉒ | クライアント | 信頼して通信を続ける | TLS のハンドシェイクを続ける |
⑬の確かめ方は、CA によって違います。社内の CA なら申請者が社内の人や機器かを、公的な CA ならそのドメインを管理しているかを確かめます。公的な CA で使われている ACME(RFC 8555)は、この確認と発行を自動化するプロトコルで、CA が HTTP(http-01)や DNS(dns-01)を通して、申請者がドメインを管理していることを確かめます。
クライアントが確かめること
⑲⑳でクライアントが確かめることを、証明書ごとに並べると次のようになります。
大事なのは、1枚ずつ「その証明書が CA として署名してよい立場か」を見ることです。たとえば、CA:FALSE のサーバ証明書の鍵で別の証明書に署名しても、その証明書は信頼されません。RFC 5280 は、cA が立っていない証明書の公開鍵で、証明書の署名を確かめてはいけないとしています。
失効:期限の前に「もう信じないで」と伝える
CRL と OCSP
秘密鍵が漏れたかもしれないとき、組織から外れた人の証明書を止めたいときなどは、期限を待たずに証明書を使えなくする必要があります。これが失効(revocation)です。失効を伝える方法には、CRL と OCSP の2つがあります。
- CRL(Certificate Revocation List):RFC 5280 は、CRL を「失効した証明書を示す、時刻つきで CA などが署名したリスト」と説明しています。新しい CRL は、1時間ごと・1日ごと・1週間ごとなど、決まった間隔で出されます。
- OCSP(Online Certificate Status Protocol):RFC 6960 で決まっている、1枚ずつ状態を聞く方法です。答えは good(失効していない)、revoked(失効している)、unknown(このレスポンダはその証明書を知らない)の3つで、確定した応答には必ず署名が付きます。
失効させる流れ
| 項目 | 最初の図(図7) | この図(失効) |
|---|---|---|
| CA の記録 | 有効(⑭) | 失効。理由も記録する(❸) |
| 失効情報 | 載っていない | 新しい CRL に載り、OCSP も revoked と答える(❹) |
| クライアントの判断 | 信頼して続ける(㉒) | 接続しない(❼) |
| 証明書そのもの | 変わらない | 変わらない。期限もそのまま |
Microsoft の AD CS のドキュメントは、失効はすべての相手に同時に届くわけではなく、相手が新しい CRL や OCSP の応答を取るまでは、失効した証明書が使えてしまうことがある、と注意しています。CA に記録するだけでなく、新しい CRL を公開して、取りに行ける場所に置くところまでが失効の作業です。
公的な証明書の決まり(CA/Browser Forum の Baseline Requirements)は、改訂(SC063)で OCSP を任意にし、CRL を必須にしました。Let’s Encrypt は、OCSP では問い合わせ先の CA に利用者の見ているサイトが分かってしまうというプライバシーの理由で、2025年5月7日に証明書から OCSP の URL を外し、2025年8月6日に OCSP のレスポンダを止めて、失効情報を CRL だけで出すようにしました。社内の CA(AD CS など)では、引き続き OCSP(オンラインレスポンダ)を使えます。
有効期間は短くなっていく
公的な TLS サーバ証明書は、有効期間そのものを短くする方向に進んでいます。CA/Browser Forum の Baseline Requirements(SC081 による改訂)は、最長の有効期間を段階的に短くすると決めています。
2026年11月の今は、最長200日の期間です。2029年には47日になり、人の手で更新するのは現実的ではなくなります。ACME や、後で見る Azure Key Vault の自動更新のように、更新を自動にすることが前提になります。社内の CA の証明書はこの決まりの対象ではありませんが、短いほど漏れたときの影響が小さいことは同じです。
試してみる(OpenSSL で CA を作る)
ここからは、テスト用の環境で OpenSSL 3.0.13 を使い、ルート CA・中間 CA・サーバ証明書を作って、検証と失効を試した結果を見ていきます。名前は試験用のドメイン(example.test)にしています。本番の CA は、この手順ではなく、AD CS や公的な CA のサービスで作ります。
ルート CA を作る(図6の①)
ルートの鍵ペアと、自己署名のルート証明書を作ります。-addext で、CA であること(CA:TRUE)と、証明書と CRL に署名する用途を付けます。
ルート CA を作る(ルート CA で操作、図6の①)
openssl req -x509 -newkey ec -pkeyopt ec_paramgen_curve:P-256 -nodes -keyout root.key -out root.crt -days 365 -subj "/CN=Demo Root CA" -addext "basicConstraints=critical,CA:TRUE" -addext "keyUsage=critical,keyCertSign,cRLSign"
ルート証明書の中身を見る
openssl x509 -in root.crt -noout -subject -issuer -ext basicConstraints,keyUsage
subject=CN = Demo Root CA issuer=CN = Demo Root CA X509v3 Basic Constraints: critical CA:TRUE X509v3 Key Usage: critical Certificate Sign, CRL Sign
発行者(issuer)と主体(subject)が同じなのが、自己署名の証明書です。このルート証明書 root.crt を、クライアントに「信頼する CA」として渡します(図6の②)。
中間 CA を作る(図6の③〜⑥)
中間 CA に付ける拡張をファイルに書きます。pathlen:0 で、この中間 CA の下には CA を置けないようにします。
inter.ext の中身
basicConstraints=critical,CA:TRUE,pathlen:0
keyUsage=critical,keyCertSign,cRLSign
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid
中間 CA の鍵ペアと CSR を作り、ルートの鍵で署名します。
中間 CA の鍵と CSR を作り、ルートで署名する(図6の③〜⑥)
openssl req -newkey ec -pkeyopt ec_paramgen_curve:P-256 -nodes -keyout inter.key -out inter.csr -subj "/CN=Demo Issuing CA" openssl x509 -req -in inter.csr -CA root.crt -CAkey root.key -CAcreateserial -out inter.crt -days 180 -extfile inter.ext
Certificate request self-signature ok subject=CN = Demo Issuing CA
中間証明書の中身を見る
subject=CN = Demo Issuing CA issuer=CN = Demo Root CA X509v3 Basic Constraints: critical CA:TRUE, pathlen:0 X509v3 Key Usage: critical Certificate Sign, CRL Sign
サーバ証明書を発行する(図7の⑩〜⑮)
中間 CA が発行の記録を残せるように、openssl ca を使います。設定ファイルに、記録のファイルや、サーバ証明書に付ける拡張(server_ext)を書いておきます。client_ext と ocsp_ext は、STEP 6 と「うまくいかないとき」で使います。
ca.cnf の中身
[ ca ] default_ca = issuing [ issuing ] database = ./index.txt new_certs_dir = ./newcerts certificate = ./inter.crt private_key = ./inter.key serial = ./serial crlnumber = ./crlnumber default_md = sha256 default_days = 90 default_crl_days = 7 policy = pol [ pol ] commonName = supplied [ server_ext ] basicConstraints = critical,CA:FALSE keyUsage = critical,digitalSignature extendedKeyUsage = serverAuth subjectAltName = DNS:api.example.test crlDistributionPoints = URI:http://pki.example.test/issuing.crl authorityInfoAccess = OCSP;URI:http://localhost:8888,caIssuers;URI:http://pki.example.test/issuing.crt [ client_ext ] basicConstraints = critical,CA:FALSE keyUsage = critical,digitalSignature extendedKeyUsage = clientAuth authorityInfoAccess = OCSP;URI:http://localhost:8888 [ ocsp_ext ] basicConstraints = critical,CA:FALSE keyUsage = critical,digitalSignature extendedKeyUsage = critical,OCSPSigning
発行の記録に使うファイルを用意する
mkdir -p newcerts && touch index.txt && echo 1000 > serial && echo 1000 > crlnumber
サーバの鍵と CSR を作り、中間 CA で発行する(図7の⑩〜⑮)
openssl req -newkey ec -pkeyopt ec_paramgen_curve:P-256 -nodes -keyout server.key -out server.csr -subj "/CN=api.example.test"
openssl ca -config ca.cnf -batch -extensions server_ext -in server.csr -out server.crt
Using configuration from ca.cnf Check that the request matches the signature Signature ok The Subject's Distinguished Name is as follows commonName :ASN.1 12:'api.example.test' Certificate is to be certified until Jan 31 06:06:38 2027 GMT (90 days) Write out database with 1 new entries Database updated
サーバ証明書の中身を見る
openssl x509 -in server.crt -noout -subject -issuer -serial -dates -ext basicConstraints,keyUsage,extendedKeyUsage,subjectAltName,crlDistributionPoints,authorityInfoAccess
subject=CN = api.example.test issuer=CN = Demo Issuing CA serial=1000 notBefore=Nov 2 06:06:38 2026 GMT notAfter=Jan 31 06:06:38 2027 GMT X509v3 Basic Constraints: critical CA:FALSE X509v3 Key Usage: critical Digital Signature X509v3 Extended Key Usage: TLS Web Server Authentication X509v3 Subject Alternative Name: DNS:api.example.test X509v3 CRL Distribution Points: Full Name: URI:http://pki.example.test/issuing.crl Authority Information Access: OCSP - URI:http://localhost:8888 CA Issuers - URI:http://pki.example.test/issuing.crt
シリアル番号 1000 の証明書ができ、index.txt に発行の記録が残りました。CRL 配布点と AIA に入っている URL は、クライアントが失効情報や中間証明書を取りに行く場所です(このテストでは、CRL 配布点の URL は使わず、CRL のファイルを直接渡します)。
チェーンを検証する(図7の⑲)
openssl verify で、信頼するルート(-CAfile)と、途中の中間証明書(-untrusted)を渡して確かめます。-untrusted は「信頼の起点にはしないが、つながりをたどるのに使う」という意味です。
中間証明書を渡して検証する
openssl verify -CAfile root.crt -untrusted inter.crt -show_chain server.crt
server.crt: OK Chain: depth=0: CN = api.example.test (untrusted) depth=1: CN = Demo Issuing CA (untrusted) depth=2: CN = Demo Root CA
中間証明書を渡さないと、ルートを持っていてもたどれません。
中間証明書を渡さずに検証する
openssl verify -CAfile root.crt server.crt
CN = api.example.test
error 20 at 0 depth lookup: unable to get local issuer certificate
error server.crt: verification failed
サーバが中間証明書を送っていないと、クライアントでこれと同じことが起きます。サーバには、サーバ証明書と一緒に中間証明書も設定します(図7の⑯⑱)。
失効させて、CRL で確かめる(図10の❷〜❼)
まず、失効させる前の CRL を作り、-crl_check で失効も確かめます。
CRL を作って、失効も確かめる
openssl ca -config ca.cnf -gencrl -out issuing.crl openssl verify -crl_check -CAfile root.crt -untrusted inter.crt -CRLfile issuing.crl server.crt
server.crt: OK
サーバの鍵が漏れたことにして、シリアル 1000 を理由 keyCompromise で失効させます。
失効させる(中間 CA で操作、図10の❷❸)
openssl ca -config ca.cnf -revoke newcerts/1000.pem -crl_reason keyCompromise
Using configuration from ca.cnf
Revoking Certificate 1000.
Database updated
CRL を作り直して中身を見る(図10の❹)
openssl ca -config ca.cnf -gencrl -out issuing.crl openssl crl -in issuing.crl -noout -text
Certificate Revocation List (CRL):
Version 2 (0x1)
Signature Algorithm: ecdsa-with-SHA256
Issuer: CN = Demo Issuing CA
Last Update: Nov 2 06:06:54 2026 GMT
Next Update: Nov 9 06:06:54 2026 GMT
CRL extensions:
X509v3 CRL Number:
4097
Revoked Certificates:
Serial Number: 1000
Revocation Date: Nov 2 06:06:54 2026 GMT
CRL entry extensions:
X509v3 CRL Reason Code:
Key Compromise
Signature Algorithm: ecdsa-with-SHA256
Signature Value:
30:45:02:20:04:d2:e5:f3:32:f4:2f:91:cd:5b:93:ae:7e:dc:
b4:40:8b:a8:a9:b2:45:a3:48:95:ad:5e:c0:68:8a:dc:13:ff:
02:21:00:9a:14:fb:da:1f:aa:ee:ef:c9:ab:e2:60:6f:54:0d:
3b:f2:27:ae:63:ff:e8:2c:ae:45:9f:8e:dc:86:91:34:55
もう一度、失効も確かめる(図10の❺〜❼)
openssl verify -crl_check -CAfile root.crt -untrusted inter.crt -CRLfile issuing.crl server.crt
CN = api.example.test
error 23 at 0 depth lookup: certificate revoked
error server.crt: verification failed
CRL には、失効した証明書のシリアル番号・日時・理由が載り、中間 CA が署名しています。Next Update は次の CRL を出す予定の日時で、設定ファイルの default_crl_days = 7 から7日後になっています。証明書そのものは何も変わっていません。変わったのは、CA が出した CRL のほうです。
OCSP で確かめる(図10の❺❻)
OCSP のレスポンダは、自分の応答に署名するための証明書(用途 OCSPSigning)を使います。比べるための「失効していない」証明書として、クライアント証明書も1枚発行しておきます。
クライアント証明書と、OCSP の署名用の証明書を発行する
openssl req -newkey ec -pkeyopt ec_paramgen_curve:P-256 -nodes -keyout client.key -out client.csr -subj "/CN=app01" openssl ca -config ca.cnf -batch -extensions client_ext -in client.csr -out client.crt openssl req -newkey ec -pkeyopt ec_paramgen_curve:P-256 -nodes -keyout ocsp.key -out ocsp.csr -subj "/CN=Demo OCSP Responder" openssl ca -config ca.cnf -batch -extensions ocsp_ext -in ocsp.csr -out ocsp.crt
OpenSSL の ocsp コマンドで、発行の記録(index.txt)を見て答えるレスポンダを 8888 番で動かします。-nrequest 2 は、2回答えたら終わる指定です。
OCSP レスポンダを起動する(中間 CA の側で操作)
openssl ocsp -index index.txt -port 8888 -rsigner ocsp.crt -rkey ocsp.key -CA inter.crt -nrequest 2
失効していない証明書を問い合わせる
openssl ocsp -issuer inter.crt -cert client.crt -url http://localhost:8888 -CAfile root.crt -verify_other inter.crt
Response verify OK client.crt: good This Update: Nov 2 06:07:00 2026 GMT
失効した証明書を問い合わせる
openssl ocsp -issuer inter.crt -cert server.crt -url http://localhost:8888 -CAfile root.crt -verify_other inter.crt
Response verify OK server.crt: revoked This Update: Nov 2 06:07:00 2026 GMT Reason: keyCompromise Revocation Time: Nov 2 06:06:54 2026 GMT
Response verify OK は、OCSP の応答の署名を確かめられたという意味です。OCSP の答えも、署名を確かめてから使います。
ここからは Microsoft の場合です
ここからは、Microsoft の環境で証明書を管理するしくみを見ます。クラウドでは Azure Key Vault で証明書と秘密鍵をまとめて管理し、社内では AD CS で自分たちの CA を動かすのが代表的な形です。
- Azure Key Vault:証明書ポリシーに、証明書の名前、鍵の種類、発行元、有効期間、ライフタイムアクション(期限の何日前・寿命の何%で、自動更新するかメールで知らせるか)を書きます。発行元が提携している CA(DigiCert・GlobalSign)なら、Key Vault が更新まで自動で行います。それ以外の CA では、Key Vault が鍵ペアと CSR を作り、CA に署名してもらった証明書を「マージ」して戻します。ポータルで作る証明書の既定は有効期間12か月、寿命の80%で自動更新です。
- 期限の監視:Key Vault は、期限の30日前に
Microsoft.KeyVault.CertificateNearExpiryのイベントを Event Grid に出します。証明書の連絡先を登録しておくと、更新の前後や更新が必要なときにメールが届きます。 - AD CS:本番では、スタンドアロンのルート CA と、ドメインに参加した発行 CA の2階層にし、発行 CA に署名したらルート CA はオフラインにするのが推奨です。AIA と CDP は証明書を発行する前に決めます。失効は、CRL を公開して相手が取れるようにするところまでが作業で、オンラインレスポンダ(OCSP)の動きは
certutil -verify -urlfetchで確かめられます。
Key Vault で証明書の新しいバージョンを作る(Azure CLI)
az keyvault certificate create --vault-name "<vault-name>" -n "<certificate-name>" -p "$(az keyvault certificate get-default-policy)"
証明書のバージョンの一覧を見る(Azure CLI)
az keyvault certificate list-versions --vault-name "<vault-name>" -n "<certificate-name>"
Microsoft の Key Vault のセキュリティのドキュメントも、公的な TLS 証明書の最長の有効期間が2026年3月から200日になり、2027年に100日、2029年に47日へ短くなる予定だとして、更新の自動化を勧めています。公的な証明書を Key Vault で手動で管理している場合は、早めに自動更新に移しておくと安心です。
よくある間違い
| 間違い | どうするか |
|---|---|
| サーバにサーバ証明書だけを設定する | 中間証明書も一緒に設定する。クライアントがルートまでたどれない |
| ルート CA で、サーバの証明書を直接発行する | ルートは中間 CA の署名にだけ使い、オフラインにする |
| 秘密鍵を CSR と一緒に CA に送る | CA に渡すのは CSR だけ。秘密鍵は作った場所から動かさない |
| 失効させたのに、CRL を公開していない | 新しい CRL を公開し、CRL 配布点から取れることを確かめるまでが失効 |
| 証明書の期限を人が覚えておく | 有効期間は短くなっていく。自動更新か、期限の通知を設定する |
| CRL 配布点の URL を、発行した後で変える | 発行済みの証明書は古い URL のまま。古い場所も、期限が切れるまで残す |
うまくいかないとき
証明書のエラーは、チェーンのどの確認で止まったかが分かると原因を絞れます。openssl verify のエラーの番号と、止まった確認を並べると次のようになります。
STEP 4・5 で見た error 20 と error 23 のほかに、残りの3つもテスト用の CA でわざと起こしてみました。まず、有効期間がすでに過ぎた証明書です。
期限切れの証明書を発行して検証する
openssl req -newkey ec -pkeyopt ec_paramgen_curve:P-256 -nodes -keyout old.key -out old.csr -subj "/CN=old.example.test"
openssl ca -config ca.cnf -batch -extensions server_ext -startdate 20260101000000Z -enddate 20260301000000Z -in old.csr -out old.crt
openssl verify -CAfile root.crt -untrusted inter.crt old.crt
CN = old.example.test
error 10 at 0 depth lookup: certificate has expired
error old.crt: verification failed
次に、クライアント認証用(clientAuth)の証明書を、サーバ用(-purpose sslserver)として確かめた場合です。同じ証明書を、クライアント用として確かめると通ります。
用途が合わない(サーバ用として確かめる)
openssl verify -CAfile root.crt -untrusted inter.crt -purpose sslserver client.crt
CN = app01
error 26 at 0 depth lookup: unsuitable certificate purpose
error client.crt: verification failed
用途が合う(クライアント用として確かめる)
openssl verify -CAfile root.crt -untrusted inter.crt -purpose sslclient client.crt
client.crt: OK
最後に、pathlen:0 の中間 CA の下に、もう1つ CA(Demo Sub CA)を作って証明書を発行した場合です。OpenSSL は発行そのものは止めませんが、検証で失敗します。
pathlen を超えた CA で発行して検証する
printf "basicConstraints=critical,CA:TRUE\nkeyUsage=critical,keyCertSign,cRLSign\n" > sub.ext openssl req -newkey ec -pkeyopt ec_paramgen_curve:P-256 -nodes -keyout sub.key -out sub.csr -subj "/CN=Demo Sub CA" openssl x509 -req -in sub.csr -CA inter.crt -CAkey inter.key -CAcreateserial -out sub.crt -days 30 -extfile sub.ext openssl req -newkey ec -pkeyopt ec_paramgen_curve:P-256 -nodes -keyout leaf2.key -out leaf2.csr -subj "/CN=leaf.example.test" openssl x509 -req -in leaf2.csr -CA sub.crt -CAkey sub.key -CAcreateserial -out leaf2.crt -days 7 cat inter.crt sub.crt > untrusted2.pem openssl verify -CAfile root.crt -untrusted untrusted2.pem leaf2.crt
CN = Demo Issuing CA
error 25 at 2 depth lookup: path length constraint exceeded
error leaf2.crt: verification failed
at 2 depth は、チェーンの下から3枚目(深さ 2、Demo Issuing CA)の pathlen:0 の制約で止まったことを表します。
| エラー | 意味 | 確かめること |
|---|---|---|
| unable to get local issuer certificate | 発行者の証明書が見つからない | 中間証明書を送っているか。社内 CA のルートを信頼済みストアに入れたか |
| certificate has expired | 有効期間を過ぎた | 証明書の notAfter。中間証明書の期限も。クライアントの時計 |
| certificate revoked | CRL や OCSP で失効と分かった | 新しい鍵で証明書を発行し直して入れ替える |
| unsuitable certificate purpose | EKU が用途と合わない | サーバ用は serverAuth、クライアント用は clientAuth が入った証明書を使う |
| path length constraint exceeded | pathlen の制約を超えた | CA の階層が、上の CA の pathlen に収まっているか |
企業での例
| 場面 | やること | 押さえどころ |
|---|---|---|
| 社内の Web システムや API に、社内 CA の証明書を使う | AD CS を2階層で作り、ルート証明書を社内の PC に配る | ルートはオフライン。AIA と CDP は発行前に決める |
| 公開している API のサーバ証明書 | 公的な CA の証明書を、ACME や Key Vault で自動更新する | 最長200日(2027年3月からは100日)。手作業の更新はやめる |
| 社員の PC の秘密鍵が漏れたかもしれない | その証明書を失効させ、CRL を公開する | 相手が新しい CRL を取るまでは使えてしまう |
| VPN や Wi-Fi で、機器を証明書で認証する | クライアント認証用(clientAuth)の証明書を配る | 次の記事(mTLS)と同じ考え方 |
まとめ
| 項目 | 内容 |
|---|---|
| PKI とは | CA が「この公開鍵は、この名前のもの」と署名して保証するしくみ |
| 証明書の中身 | シリアル・発行者・有効期間・主体・公開鍵・拡張(CA:TRUE/FALSE・用途・SAN・CDP・AIA)と CA の署名 |
| チェーン | ルート(自己署名・オフライン)→ 中間(発行 CA)→ サーバ。サーバは中間証明書も送る |
| 確かめること | 1枚ずつ署名・期限・CA の立場・失効。サーバ証明書は名前と用途も |
| 失効 | CRL(まとめて取る)と OCSP(1枚ずつ聞く)。公開して相手が取るまでが失効 |
| 今の流れ | 公的な TLS 証明書は最長200日から47日へ。更新の自動化が前提 |
| Microsoft の場合 | Key Vault で期限と自動更新を、AD CS で社内の CA の階層と失効を管理する |
参考にした資料
この記事は、次の標準と公式ドキュメントで内容を確かめて書きました。仕様や対応状況は変わることがあるので、最新の情報はリンク先で確かめてください。
- RFC 5280: Internet X.509 Public Key Infrastructure Certificate and Certificate Revocation List (CRL) Profile(IETF):証明書の3つの部分と項目、CA の署名による結びつき、自己署名証明書と証明書のつながり、basicConstraints と pathLenConstraint、keyUsage、SAN、CRL の説明と発行の間隔、失効の理由
- RFC 6960: X.509 Internet Public Key Infrastructure Online Certificate Status Protocol – OCSP(IETF):good・revoked・unknown の意味、応答の署名
- RFC 2986: PKCS #10: Certification Request Syntax Specification Version 1.7(IETF):CSR に入るものと、申請者の署名
- RFC 8555: Automatic Certificate Management Environment (ACME)(IETF):ドメインの確認と発行の自動化、http-01 と dns-01
- Baseline Requirements for the Issuance and Management of Publicly-Trusted TLS Server Certificates(CA/Browser Forum):最長の有効期間の予定(200日・100日・47日)、SC063(OCSP を任意にし CRL を必須にする改訂)
- Ending OCSP Support in 2025(Let’s Encrypt):OCSP を止めた日付とプライバシーの理由、CRL への移行
- PKI design considerations using Active Directory Certificate Services・Configure a certification authority to use ML-DSA(Microsoft Learn):AIA と CDP を発行前に決めること、証明書の確認が失敗すると困る場面、スタンドアロンのルート CA をオフラインにする推奨と2階層の構成
- Operate certificate revocation, CRL publication, and CDP changes in AD CS・Secure, monitor, renew, and scale Online Responders(Microsoft Learn):失効がすぐには届かないこと、CDP を変えても発行済みの証明書は古いままなこと、certutil -verify -urlfetch
- Microsoft Cloud PKI fundamentals(Microsoft Learn):ルート CA が自己発行で、信頼済みルートストアに入れて信頼すること、中間・発行・下位 CA が同じ役割の呼び名であること
- About Azure Key Vault certificates・Renew your Azure Key Vault certificates・Tutorial: Configure certificate autorotation in Key Vault(Microsoft Learn):証明書ポリシー、ライフタイムアクション、提携 CA と自動更新、CSR のマージ、既定の12か月と80%、Azure CLI
- Secure your Azure Key Vault certificates(Microsoft Learn):公的な TLS 証明書の有効期間の短縮予定、期限の30日前のイベント、社内証明書の期間の考え方
あとがき
ルート CA から順に作ってみると、証明書の「つながり」は、発行者の名前と署名を1段ずつたどっているだけだと、手で確かめられました。一方で、失効は証明書そのものではなく CA が出すリストの側で起きることや、公開して相手が取るまで効かないことは、実際に CRL を作り直して初めて実感できたところです。次の記事では、この証明書をクライアントにも持たせて相手を確かめる mTLS を扱います。
コメント