X.509証明書とPKIの基礎知識まとめ
🔐 公開鍵基盤(PKI)とは?
- デジタル証明書を用いて、安全な通信や認証を可能にする枠組み。
- 信頼の連鎖(Trust Chain)に基づいて証明書の正当性を保証。
- 主な構成要素:
- 公開鍵/秘密鍵ペア
- 認証局(CA: Certificate Authority)
- 登録局(RA: Registration Authority)
- 証明書失効リスト(CRL)、OCSP
📜 X.509証明書の基本構造
X.509v3 証明書には以下の主なフィールドが含まれる:
- Version: 通常は v3
- Serial Number: 証明書ごとの一意な識別子
- Signature Algorithm: 使用される署名アルゴリズム(例:sha256WithRSAEncryption)
- Issuer: 発行者(CA)の情報
- Validity: 有効期間(Not Before / Not After)
- Subject: 証明書の所有者情報
- Subject Public Key Info: 公開鍵とそのアルゴリズム
- Extensions: 拡張フィールド(X.509v3)
🧩 X.509v3 証明書拡張の例
拡張 |
説明 |
備考 |
Basic Constraints |
この証明書がCAかどうか |
CA:TRUE / FALSE |
Key Usage |
使用目的の指定 |
digitalSignature、keyEncipherment など |
Extended Key Usage |
より細かい使用目的 |
serverAuth、clientAuth など |
Subject Alternative Name (SAN) |
複数のDNS/IPを含める |
Let's Encryptなどで必須 |
CRL Distribution Points |
CRLの取得先URL |
失効確認用 |
Authority Information Access (AIA) |
発行元CAの情報 |
OCSPや中間証明書URL |
🔧 OpenSSL コマンドと操作例
🔑 鍵の生成
openssl genpkey -algorithm RSA -out private.key -pkeyopt rsa_keygen_bits:2048
📝 CSRの作成
openssl req -new -key private.key -out request.csr -subj "/CN=example.com"
🖊️ 自己署名証明書の作成(テスト用)
openssl req -x509 -key private.key -in request.csr -out cert.pem -days 365
📖 証明書の内容確認
openssl x509 -in cert.pem -noout -text
- CAによる証明書発行ログを公開ログサーバに登録
- ブラウザがSSL証明書の正当性をリアルタイムで確認
- 攻撃者による不正な証明書発行の検知に有効
📦 フォーマットの違い
形式 |
拡張子 |
内容 |
PEM |
.pem、.crt、.key |
Base64 + ヘッダ |
DER |
.der、.cer |
バイナリ形式 |
PKCS#12 |
.p12、.pfx |
鍵+証明書を1つのファイルに |
🌐 Let's Encrypt / ACME / certbot
- Let's Encrypt: 無料のSSL証明書提供CA
- ACME: 証明書の自動取得・更新プロトコル
- certbot: ACMEクライアントの代表例
certbot certonly --webroot -w /var/www/html -d example.com
🛠️ CFSSL(Cloudflare製)
- JSONベースの設定・操作が特徴の証明書管理ツール
- サーバ証明書、CA証明書の発行・署名・失効が可能
- REST APIによる操作も可能
📉 証明書の失効・無効化
❌ CRL (Certificate Revocation List)
❌ OCSP (Online Certificate Status Protocol)
- 証明書の状態をリアルタイムで確認するためのプロトコル
📚 学習のポイントまとめ
🧠 Detail
- X.509はITU-Tが定義した公開鍵証明書の標準仕様(Recommendation X.509)。
- 公開鍵基盤(PKI)において、公開鍵とその所有者の関連性を第三者(CA)が保証するための仕組み。
- 現在主に使用されているのは **X.509v3**(バージョン3)。
🔧 X.509 証明書の構造(ASN.1 DERで定義)
- 証明書はASN.1で記述され、DER(Distinguished Encoding Rules)形式で符号化される。
- PEM形式(Base64 + ヘッダ/フッタ)への変換は可逆。
🧬 構成フィールド一覧
フィールド |
説明 |
Version |
v1, v2, v3のいずれか(通常はv3) |
Serial Number |
CAが一意に割り当てる整数識別子 |
Signature Algorithm |
署名アルゴリズム(例:sha256WithRSAEncryption) |
Issuer |
CAの識別情報(Distinguished Name) |
Validity |
Not Before / Not After による有効期間 |
Subject |
証明書所有者の識別情報(Distinguished Name) |
Subject Public Key Info |
公開鍵アルゴリズム + 公開鍵本体 |
Extensions |
X.509v3で導入された拡張領域 |
Signature Algorithm |
署名アルゴリズムの繰り返し(署名情報に付随) |
Signature Value |
Issuerの秘密鍵による署名 |
🧩 X.509v3 Extensions(拡張)
- 証明書の用途や制約を明示的に指定できる柔軟な設計。
- 各拡張には「critical」ビットがあり、未対応のcritical拡張があれば証明書は無効と見なされる。
🔬 主な拡張一覧
拡張 |
用途 |
備考 |
Basic Constraints |
CAかエンドエンティティかの指定 |
CA:TRUE / FALSE |
Key Usage |
使用目的の制限 |
digitalSignature、keyCertSignなど |
Extended Key Usage |
応用レベルでの用途 |
serverAuth、clientAuth、codeSigningなど |
Subject Alternative Name (SAN) |
複数のFQDN、IP、URIなどの紐付け |
Common Nameと異なる主体名を補完 |
Authority Key Identifier |
発行元のキー識別子 |
中間CAの照合に使用 |
Subject Key Identifier |
自身のキー識別子 |
証明書チェーンのビルドに有用 |
CRL Distribution Points |
CRLの取得先 |
証明書失効確認に使用 |
Authority Information Access (AIA) |
OCSPレスポンダや中間証明書へのURL |
OCSPステータスやチェーン構築に使用 |
🔄 証明書のライフサイクル
- 証明書は「発行→利用→更新/失効→期限切れ」というサイクルを持つ。
- ライフサイクル全体を管理するためには以下の構成が必要:
⛓️ 信頼の連鎖(Trust Chain)
- ルートCA(自己署名) → 中間CA → エンドエンティティ(サーバ/クライアント)証明書
- ブラウザやOSはルート証明書を信頼し、それに連なる署名チェーンを検証
❌ 証明書の失効
- CRL(Certificate Revocation List): 定期更新方式(一覧をダウンロード)
- OCSP(Online Certificate Status Protocol): リアルタイム問い合わせ方式
- OCSP Stapling: サーバ側でOCSPレスポンスをキャッシュしTLSハンドシェイク中に提示
🌐 Certificate Transparency(CT)
- 不正な証明書発行を防止するGoogle主導の仕組み
- CAはすべての証明書発行ログを**公開CTログサーバ**に登録
- ブラウザは証明書に**SCT(Signed Certificate Timestamp)**が含まれているかを検証
- 攻撃者による「偽の証明書発行」を**監視可能な状態**にする
CT導入の背景
- DigiNotar、CNNICなどのCAが不正に証明書を発行した事件
- ログ監査によるCAの監視と透明性の向上
🔐 X.509とPKIのセキュリティ課題
- CAの鍵漏洩・ハッキング(ルートCAの信頼崩壊)
- 鍵の長期運用によるセキュリティリスク(RSA2048の寿命問題)
- 証明書発行の自動化と信頼性のトレードオフ(Let's Encryptのケース)
🔧 OpenSSLでの操作例(実践)
🔑 鍵の生成
openssl genpkey -algorithm RSA -out private.key -pkeyopt rsa_keygen_bits:2048
📝 CSR(証明書署名要求)の生成
openssl req -new -key private.key -out request.csr -subj "/CN=example.com"
🖊️ 自己署名証明書(テスト用途)
openssl req -x509 -key private.key -in request.csr -out cert.pem -days 365
🔍 証明書内容の確認
openssl x509 -in cert.pem -noout -text
以下は、**X.509証明書とSSL/TLS・Apache HTTPD (mod_ssl)・OpenSSL の専門家向け解説資料**です。
アットウィキ形式でコピペしやすいように、`|`区切りテーブル+コードブロック形式で構成しています。
🔐 SSL/TLS プロトコルの概要**
バージョン |
特徴 |
状態 |
TLS 1.3 |
暗号スイート簡素化、ハンドシェイク高速化 |
推奨 |
TLS 1.2 |
業界標準、AEAD暗号対応 |
推奨 |
TLS 1.0/1.1 |
SHA-1やRC4など非推奨 |
非推奨・廃止 |
SSL 3.0/2.0 |
脆弱(POODLEなど) |
廃止済み |
暗号スイート構成要素:
- 鍵交換方式: ECDHE, DHE
- 認証: RSA, ECDSA
- 暗号: AES-GCM, ChaCha20-Poly1305
- MAC: HMAC-SHA256(※TLS1.3では不要)
⚙️ Apache HTTPD (mod_ssl) 基本設定**
plugin_code is not found. please feed back @wiki.
```
LoadModule ssl_module modules/mod_ssl.so
Listen 443 https
<VirtualHost *:443>
ServerName example.com
SSLEngine on
SSLCertificateFile /etc/ssl/certs/example.crt
SSLCertificateKeyFile /etc/ssl/private/example.key
SSLCertificateChainFile /etc/ssl/certs/chain.pem
SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1
SSLCipherSuite HIGH:!aNULL:!MD5:!RC4
SSLHonorCipherOrder on
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
DocumentRoot /var/www/html
</VirtualHost>
```
🏷️ SNI 対応と HSTS 設定**
- SNI (Server Name Indication)
複数のSSL証明書を1 IPでホスト可能。VirtualHost を ServerName で分けて設定。
- HSTS (HTTP Strict Transport Security)
常時HTTPSを強制。以下のヘッダで実装:
```
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
```
🔐 クライアント証明書認証**
plugin_code is not found. please feed back @wiki.
```
<VirtualHost *:443>
SSLEngine on
SSLCertificateFile /path/to/server.crt
SSLCertificateKeyFile /path/to/server.key
SSLCACertificateFile /path/to/ca.crt
SSLVerifyClient require
SSLVerifyDepth 2
<Location />
SSLRequire %{SSL_CLIENT_S_DN_CN} eq "trusted-client"
</Location>
</VirtualHost>
```
🧾 OCSP Stapling の設定**
```
SSLUseStapling on
SSLStaplingResponderTimeout 5
SSLStaplingReturnResponderErrors off
SSLStaplingCache shmcb:/var/run/ocsp(128000)
SSLCACertificateFile /etc/ssl/certs/ca-bundle.crt
```
OCSP URI確認:
```
openssl x509 -in cert.pem -noout -ocsp_uri
```
🧪 OpenSSLによるテスト手法**
操作 |
コマンド |
---- |
-------- |
サーバ接続テスト |
`openssl s_client -connect example.com:443` |
OCSPレスポンス確認 |
`openssl s_client -connect example.com:443 -status` |
クライアント証明書付き接続 |
`openssl s_client -connect example.com:443 -cert client.crt -key client.key -CAfile ca.crt` |
🛠️ トラブルシュート早見表**
エラー例 |
原因 |
対応 |
-------- |
----- |
---- |
handshake failure |
TLSバージョン/暗号不一致 |
`SSLProtocol`, `SSLCipherSuite`見直し |
unable to verify the first certificate |
中間証明書の欠如 |
`SSLCertificateChainFile`の指定 |
client certificate not provided |
クライアント証明書なし |
ブラウザor curlに証明書を設定 |
必要に応じてさらに詳細展開できます。応用例や自動化スクリプトが必要であれば教えてください。
最終更新:2025年04月24日 07:39