はじめに
本記事では、LPIC 331.1 出題範囲の OpenSSL / X.509 公開鍵基盤(PKI)を VirtualBox + Vagrant で構築した環境でハンズオン学習した記録を記載しています。
-
対象範囲
- openssl(鍵生成・証明書管理・フォーマット変換)
- X.509 証明書ライフサイクル(CSR, 署名, 失効)
- 認証局(CA)の構築と管理
- PEM / DER / PKCS 形式変換
- CRL(証明書失効リスト)
- OCSP(オンライン証明書状態プロトコル)
- 参考 : LPI 303 試験概要
-
検証時利用環境
- ホストOS:Ubuntu 22.04.3
- VirtualBox:7.0.26r168464
- Vagrant:2.4.1
0. 環境の準備
0-1. VagrantFile の作成
作業用ディレクトリを作成する
mkdir openssl_pki
cd openssl_pki
VagrantFile を作成する ※学習環境として以下を定義
- OS:Ubuntu 22.04 LTS
- CPU:2コア
- メモリ:2GB
- openssl インストール済み
- ca-certificates インストール済み
- CA ディレクトリ(/etc/ssl/myCA)初期化済み(index.txt, serial, crlnumber)
クリックで開く
# -*- mode: ruby -*-
# vi: set ft=ruby :
#
# LPIC 331 331.1 — openssl_pki 学習環境
# カバートピック: openssl, X.509証明書, PKI, CSR, CRL, OCSP, PEM, DER, PKCS
Vagrant.configure("2") do |config|
config.vm.box = "ubuntu/jammy64" # Ubuntu 22.04 LTS
config.vm.hostname = "pki-lab"
config.vm.network "private_network", ip: "192.168.56.10"
config.vm.provider "virtualbox" do |vb|
vb.name = "lpic331-openssl-pki"
vb.memory = 2048
vb.cpus = 2
end
# -------------------------------------------------------
# プロビジョニング
# -------------------------------------------------------
config.vm.provision "shell", inline: <<-SHELL
set -eux
export DEBIAN_FRONTEND=noninteractive
echo "=== apt update ==="
apt-get update -y
# -------------------------------------------------------
# OpenSSL / PKI ツール
# -------------------------------------------------------
echo "=== openssl / ca-certificates ==="
apt-get install -y \
openssl \
ca-certificates
# -------------------------------------------------------
# CA ディレクトリ構造の初期化
# -------------------------------------------------------
echo "=== CA directory structure ==="
mkdir -p /etc/ssl/myCA/{certs,crl,newcerts,private}
chmod 700 /etc/ssl/myCA/private
touch /etc/ssl/myCA/index.txt
echo 1000 > /etc/ssl/myCA/serial
echo 1000 > /etc/ssl/myCA/crlnumber
cp /etc/ssl/openssl.cnf /etc/ssl/myCA/openssl.cnf
# -------------------------------------------------------
# 共通ユーティリティ
# -------------------------------------------------------
echo "=== utilities ==="
apt-get install -y \
curl wget git vim tree \
net-tools lsof
echo "=== provisioning done ==="
SHELL
end
0-2. VM の起動
vagrant up
初回は Ubuntu イメージのダウンロードとプロビジョニングが実行されます(5〜10分程度)。
0-3. VM へのログイン
vagrant ssh
0-4. root に昇格
sudo -i
1. X.509 証明書の基礎
概要
- X.509 は ITU-T が標準化した公開鍵証明書のフォーマット
- 証明書には Subject(所有者)、Issuer(発行者)、有効期限、公開鍵、署名が含まれる
- X.509v3 からは Extensions(拡張フィールド)が追加され、用途・SAN などを指定できる
- 信頼の連鎖(Trust Chain):ルート CA → 中間 CA → エンド証明書の階層構造
- 証明書透明性(CT: Certificate Transparency):証明書の公開ログで不正発行を監視する仕組み
1-1. 証明書の内容確認
既存の証明書を確認する
# PEM 形式の証明書を人間が読める形式で表示
openssl x509 -in /etc/ssl/certs/ca-certificates.crt -noout -text 2>/dev/null
Certificate:
Data:
Version: 3 (0x2)
Serial Number: 6828503384748696800 (0x5ec3b7a6437fa4e0)
Signature Algorithm: sha1WithRSAEncryption
Issuer: CN = ACCVRAIZ1, OU = PKIACCV, O = ACCV, C = ES
Validity
Not Before: May 5 09:37:37 2011 GMT
Not After : Dec 31 09:37:37 2030 GMT
Subject: CN = ACCVRAIZ1, OU = PKIACCV, O = ACCV, C = ES
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (4096 bit)
Modulus:
00:9b:a9:ab:bf:61:4a:97:af:2f:97:66:9a:74:5f:
d0:d9:96:fd:cf:e2:e4:66:ef:1f:1f:47:33:c2:44:
<中略>
Exponent: 65537 (0x10001)
X509v3 extensions:
Authority Information Access:
CA Issuers - URI:http://www.accv.es/fileadmin/Archivos/certificados/raizaccv1.crt
OCSP - URI:http://ocsp.accv.es
X509v3 Subject Key Identifier:
D2:87:B4:E3:DF:37:27:93:55:F6:56:EA:81:E5:36:CC:8C:1E:3F:BD
X509v3 Basic Constraints: critical
CA:TRUE
X509v3 Authority Key Identifier:
D2:87:B4:E3:DF:37:27:93:55:F6:56:EA:81:E5:36:CC:8C:1E:3F:BD
X509v3 Certificate Policies:
Policy: X509v3 Any Policy
User Notice:
Explicit Text:
CPS: http://www.accv.es/legislacion_c.htm
X509v3 CRL Distribution Points:
Full Name:
URI:http://www.accv.es/fileadmin/Archivos/certificados/raizaccv1_der.crl
X509v3 Key Usage: critical
Certificate Sign, CRL Sign
X509v3 Subject Alternative Name:
email:accv@accv.es
Signature Algorithm: sha1WithRSAEncryption
Signature Value:
97:31:02:9f:e7:fd:43:67:48:44:14:e4:29:87:ed:4c:28:66:
d0:8f:35:da:4d:61:b7:4a:97:4d:b5:db:90:e0:05:2e:0e:c6:
<中略>
# 有効期限のみ確認
openssl x509 -in /etc/ssl/certs/ISRG_Root_X1.pem -noout -dates
notBefore=Jun 4 11:04:38 2015 GMT
notAfter=Jun 4 11:04:38 2035 GMT
# Subject / Issuer のみ確認
openssl x509 -in /etc/ssl/certs/ISRG_Root_X1.pem -noout -subject -issuer
subject=C = US, O = Internet Security Research Group, CN = ISRG Root X1
issuer=C = US, O = Internet Security Research Group, CN = ISRG Root X1
証明書のフィールド一覧
| フィールド | 説明 |
|---|---|
| Version | 証明書バージョン(通常 v3) |
| Serial Number | CA が発行した一意のシリアル番号 |
| Signature Algorithm | 署名アルゴリズム(例: sha256WithRSAEncryption) |
| Issuer | 発行者 CA の識別名(DN) |
| Validity | Not Before / Not After(有効期間) |
| Subject | 証明書所有者の識別名(DN) |
| Subject Public Key Info | 公開鍵とアルゴリズム |
| Extensions | v3 拡張フィールド |
X.509v3 主要拡張フィールド
| 拡張フィールド | 説明 |
|---|---|
| Basic Constraints | CA 証明書かどうか(CA:TRUE)、パス長制限 |
| Key Usage | 鍵の用途(digitalSignature, keyCertSign など) |
| Extended Key Usage | 拡張用途(serverAuth, clientAuth など) |
| Subject Alternative Name | SAN(複数ドメイン・IPを指定) |
| CRL Distribution Points | CRL の配布場所 URL |
| Authority Information Access | OCSP URL、発行者証明書 URL |
| Subject Key Identifier | 公開鍵のハッシュ値(識別子) |
| Authority Key Identifier | 発行者公開鍵のハッシュ値 |
2. 鍵ペアの生成と管理
概要
openssl genrsaで RSA 秘密鍵を生成する(2048bit 以上を推奨)openssl ecparam+openssl genpkeyで EC(楕円曲線)鍵を生成する- 秘密鍵はパスフレーズで暗号化して保護できる(AES-256など)
openssl pkey/openssl rsa/openssl ecで鍵の確認・変換を行う
2-1. RSA 鍵の生成
作業ディレクトリの準備
mkdir -p /root/pki-lab/keys
cd /root/pki-lab/keys
RSA 秘密鍵の生成(パスフレーズなし)
# 2048bit RSA 秘密鍵を生成
openssl genrsa -out server.key 2048
# 鍵の内容確認
openssl rsa -in server.key -text -noout
# 公開鍵を取り出す
openssl rsa -in server.key -pubout -out server.pub
RSA 秘密鍵の生成(AES-256 で暗号化)
# パスフレーズ付き秘密鍵(-aes256 オプション)
openssl genrsa -aes256 -out encrypted.key 4096
Enter PEM pass phrase: # パスフレーズの入力
Verifying - Enter PEM pass phrase: # パスフレーズの再入力
# パスフレーズを取り除く
openssl rsa -in encrypted.key -out decrypted.key
Enter pass phrase for encrypted.key: # パスフレーズの入力
writing RSA key
2-2. EC 鍵の生成
利用可能な曲線を確認
openssl ecparam -list_curves
EC 秘密鍵の生成
# P-256 楕円曲線鍵の生成
openssl ecparam -genkey -name prime256v1 -out ec.key
# 鍵の確認
openssl ec -in ec.key -text -noout
read EC key
Private-Key: (256 bit)
priv:
9a:6e:76:42:9b:51:8c:04:91:c4:57:96:09:05:ed:
<中略>
pub:
04:38:07:1e:b1:e7:a8:38:9d:be:fb:f9:0b:19:16:
<中略>
ASN1 OID: prime256v1
NIST CURVE: P-256
3. 認証局(CA)の構築
概要
- 自己署名のルート CA 証明書を作成し、CA として機能させる
openssl req -x509コマンドでルート CA 証明書を生成する- CA の状態は
index.txt(発行記録),serial(次のシリアル番号),crlnumberで管理する openssl.cnfの[ CA_default ]セクションで CA の動作を設定する
3-1. ルート CA の作成
検証環境のCA ディレクトリ構造の確認
ls -la /etc/ssl/myCA/
# certs/: 発行済み証明書
# crl/: CRL ファイル
# newcerts/: 新規発行証明書(自動コピー)
# private/: CA 秘密鍵
openssl.cnf の CA 設定を編集
# CA のデフォルトセクションを確認
grep -A 20 "\[ CA_default \]" /etc/ssl/myCA/openssl.cnf
[ CA_default ]
dir = ./demoCA # Where everything is kept
certs = $dir/certs # Where the issued certs are kept
crl_dir = $dir/crl # Where the issued crl are kept
database = $dir/index.txt # database index file.
#unique_subject = no # Set to 'no' to allow creation of
# several certs with same subject.
new_certs_dir = $dir/newcerts # default place for new certs.
certificate = $dir/cacert.pem # The CA certificate
serial = $dir/serial # The current serial number
crlnumber = $dir/crlnumber # the current crl number
# must be commented out to leave a V1 CRL
crl = $dir/crl.pem # The current CRL
private_key = $dir/private/cakey.pem # The private key
x509_extensions = usr_cert # The extensions to add to the cert
# Comment out the following two lines for the "traditional"
# (and highly broken) format.
# dir の設定を変更
sed -i 's|^dir.*=.*demoCA|dir = /etc/ssl/myCA|' /etc/ssl/myCA/openssl.cnf
# 確認
grep "^dir" /etc/ssl/myCA/openssl.cnf
dir = /etc/ssl/myCA # Where everything is kept
dir = /etc/ssl/myCA # TSA root directory
ルート CA 秘密鍵の生成
cd /etc/ssl/myCA
# パスフレーズなしで生成(学習用途)
openssl genrsa -out private/cakey.pem 4096
chmod 400 private/cakey.pem
ルート CA 証明書の自己署名
openssl req -x509 -new -nodes \
-key private/cakey.pem \
-sha256 \
-days 3650 \
-out cacert.pem \
-subj "/C=JP/ST=Tokyo/L=Shinjuku/O=MyOrg CA/OU=IT/CN=MyOrg Root CA"
# 証明書の確認
openssl x509 -in cacert.pem -noout -text | head -20
Certificate:
Data:
Version: 3 (0x2)
Serial Number:
47:72:b4:5e:01:47:54:f7:93:eb:b1:d4:5a:4d:4a:7a:98:0c:6f:ad
Signature Algorithm: sha256WithRSAEncryption
Issuer: C = JP, ST = Tokyo, L = Shinjuku, O = MyOrg CA, OU = IT, CN = MyOrg Root CA
Validity
Not Before: May 3 17:04:26 2026 GMT
Not After : Apr 30 17:04:26 2036 GMT
Subject: C = JP, ST = Tokyo, L = Shinjuku, O = MyOrg CA, OU = IT, CN = MyOrg Root CA
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (4096 bit)
Modulus:
00:cd:3c:d0:07:e1:19:db:aa:18:de:77:f5:94:88:
38:8b:22:f5:95:58:84:d9:8a:1e:a7:d0:ed:d2:84:
a3:b4:90:e2:ad:cc:1a:ce:b3:00:9f:70:49:06:95:
ed:5b:21:79:50:e6:c1:55:69:17:97:0a:52:f7:b9:
9c:0f:eb:56:67:33:b7:c6:28:83:df:59:ea:39:3e:
ルート CA の主要属性確認
# Subject と Issuer が同一(自己署名)なことを確認
openssl x509 -in cacert.pem -noout -subject -issuer
subject=C = JP, ST = Tokyo, L = Shinjuku, O = MyOrg CA, OU = IT, CN = MyOrg Root CA
issuer=C = JP, ST = Tokyo, L = Shinjuku, O = MyOrg CA, OU = IT, CN = MyOrg Root CA
# Basic Constraints: CA:TRUE を確認
openssl x509 -in cacert.pem -noout -text | grep -A 3 "Basic Constraints"
X509v3 Basic Constraints: critical
CA:TRUE
Signature Algorithm: sha256WithRSAEncryption
Signature Value:
4. CSR の生成と証明書の署名
概要
- CSR(Certificate Signing Request)は公開鍵と Subject 情報を CA に送る要求書
openssl reqコマンドで CSR を生成する- CA は CSR に署名して証明書を発行する(
openssl caまたはopenssl x509 -req) - Subject Alternative Name(SAN)は CSR に含めるか、CA が付与する
4-1. サーバ証明書 CSR の生成
作業ディレクトリの準備
mkdir -p /root/pki-lab/server
cd /root/pki-lab/server
サーバ秘密鍵の生成
openssl genrsa -out server.key 2048
CSR の生成
openssl req -new \
-key server.key \
-out server.csr \
-subj "/C=JP/ST=Tokyo/L=Shinjuku/O=MyOrg CA/OU=Web/CN=www.example.com"
# CSR の内容確認
openssl req -in server.csr -noout -text
Certificate Request:
Data:
Version: 1 (0x0)
Subject: C = JP, ST = Tokyo, L = Shinjuku, O = MyOrg CA, OU = Web, CN = www.example.com
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (2048 bit)
Modulus:
00:cb:9c:43:27:9b:64:9e:38:02:a0:c1:01:d3:49:
59:f1:a3:c0:9c:f4:e6:d2:49:5d:87:35:2f:5e:ec:
<中略>
Exponent: 65537 (0x10001)
Attributes:
(none)
Requested Extensions:
Signature Algorithm: sha256WithRSAEncryption
Signature Value:
34:0e:eb:63:69:4a:75:4f:e9:b1:f6:91:fc:86:14:3b:41:c3:
e2:d6:03:0c:fb:27:81:3d:55:1b:0c:6e:f8:38:af:c0:a7:7f:
<中略>
SAN 付き CSR の生成
cat > /root/pki-lab/server/san.cnf << 'EOF'
[req]
default_bits = 2048
prompt = no
default_md = sha256
req_extensions = req_ext
distinguished_name = dn
[dn]
C = JP
ST = Tokyo
L = Shinjuku
O = MyOrg CA
CN = www.example.com
[req_ext]
subjectAltName = @alt_names
[alt_names]
DNS.1 = www.example.com
DNS.2 = example.com
IP.1 = 192.168.56.10
EOF
openssl req -new \
-key server.key \
-out server-san.csr \
-config san.cnf
# SAN が含まれているか確認
openssl req -in server-san.csr -noout -text | grep -A 5 "Subject Alternative"
X509v3 Subject Alternative Name:
DNS:www.example.com, DNS:example.com, IP Address:192.168.56.10
Signature Algorithm: sha256WithRSAEncryption
Signature Value:
7a:b4:b3:d1:54:a3:fb:9d:57:37:fb:e5:4f:e5:b4:f6:5c:51:
be:5f:a2:08:46:55:6f:43:ab:a2:04:23:a4:c6:73:84:88:1c:
** CSR設定ファイル(san.cnf)のまとめ **
- [req] セクション
| 項目 | 設定値 | 意味 | 補足 |
|---|---|---|---|
| default_bits | 2048 | 鍵長(RSA) | 現在の標準的な強度 |
| prompt | no | 対話入力を無効化 | 自動化・スクリプト向け |
| default_md | sha256 | 署名ハッシュアルゴリズム | SHA-1は非推奨 |
| req_extensions | req_ext | 拡張設定の参照先 | SANを含めるために必須 |
| distinguished_name | dn | Subject情報の参照先 | 証明書の所有者情報 |
- [dn] セクション
| 項目 | 設定値 | 意味 | 補足 |
|---|---|---|---|
| C | JP | 国コード | ISO形式 |
| ST | Tokyo | 都道府県 | 任意 |
| L | Shinjuku | 市区町村 | 任意 |
| O | MyOrg CA | 組織名 | 任意 |
| CN | www.example.com | コモンネーム | 現在はSANが優先 |
- ■ [req_ext] セクション
| 項目 | 設定値 | 意味 | 補足 |
|---|---|---|---|
| subjectAltName | @alt_names | SAN設定の参照 | 現代TLSで必須 |
- ■ [alt_names] セクション
| 項目 | 設定値 | 意味 | 補足 |
|---|---|---|---|
| DNS.1 | www.example.com | DNS名 | メインドメイン |
| DNS.2 | example.com | DNS名 | サブなしドメイン |
| IP.1 | 192.168.56.10 | IPアドレス | IPアクセス対応 |
4-2. CSR への署名(証明書発行)
CA を使って CSR に署名する
cd /etc/ssl/myCA
# openssl ca コマンドで署名(index.txt に記録される)
openssl ca \
-batch \
-config openssl.cnf \
-in /root/pki-lab/server/server.csr \
-out /root/pki-lab/server/server.crt \
-days 365 \
-notext
Using configuration from openssl.cnf
Check that the request matches the signature
Signature ok
Certificate Details:
Serial Number: 4096 (0x1000)
Validity
Not Before: May 3 17:16:33 2026 GMT
Not After : May 3 17:16:33 2027 GMT
Subject:
countryName = JP
stateOrProvinceName = Tokyo
organizationName = MyOrg CA
organizationalUnitName = Web
commonName = www.example.com
X509v3 extensions:
X509v3 Basic Constraints:
CA:FALSE
X509v3 Subject Key Identifier:
36:B0:B5:51:24:0E:5B:62:1C:19:1F:39:CD:98:61:7B:0A:8A:72:82
X509v3 Authority Key Identifier:
C0:56:7E:07:1C:41:84:27:2F:76:E2:62:0D:ED:94:89:9C:81:5B:9F
Certificate is to be certified until May 3 17:16:33 2027 GMT (365 days)
Write out database with 1 new entries
Data Base Updated
# 発行記録の確認
cat /etc/ssl/myCA/index.txt
V 270503171633Z 1000 unknown /C=JP/ST=Tokyo/O=MyOrg CA/OU=Web/CN=www.example.com
# 証明書の確認
openssl x509 -in /root/pki-lab/server/server.crt -noout -text | head -20
Certificate:
Data:
Version: 3 (0x2)
Serial Number: 4096 (0x1000)
Signature Algorithm: sha256WithRSAEncryption
Issuer: C = JP, ST = Tokyo, L = Shinjuku, O = MyOrg CA, OU = IT, CN = MyOrg Root CA
Validity
Not Before: May 3 17:16:33 2026 GMT
Not After : May 3 17:16:33 2027 GMT
Subject: C = JP, ST = Tokyo, O = MyOrg CA, OU = Web, CN = www.example.com
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (2048 bit)
Modulus:
00:cb:9c:43:27:9b:64:9e:38:02:a0:c1:01:d3:49:
59:f1:a3:c0:9c:f4:e6:d2:49:5d:87:35:2f:5e:ec:
9d:fc:a3:19:e1:e4:de:95:86:a5:e0:56:a7:b6:f7:
59:30:ed:38:40:51:52:15:8d:fc:e0:5f:e8:08:c2:
fc:02:5f:25:47:1c:30:ee:a0:23:c5:2b:de:e8:35:
20:db:83:83:93:35:21:30:cb:46:12:8f:24:f7:ae:
証明書チェーンの検証
# CA 証明書で サーバ証明書を検証
openssl verify \
-CAfile /etc/ssl/myCA/cacert.pem \
/root/pki-lab/server/server.crt
/root/pki-lab/server/server.crt: OK
4-3. クライアント用の証明書の発行
mkdir -p /root/pki-lab/client
cd /root/pki-lab/client
# クライアント秘密鍵と CSR
openssl genrsa -out client.key 2048
openssl req -new \
-key client.key \
-out client.csr \
-subj "/C=JP/ST=Tokyo/O=MyOrg CA/CN=client01"
# CA で署名
openssl ca \
-batch \
-config /etc/ssl/myCA/openssl.cnf \
-in client.csr \
-out client.crt \
-days 365 \
-notext
Using configuration from /etc/ssl/myCA/openssl.cnf
Check that the request matches the signature
Signature ok
Certificate Details:
Serial Number: 4097 (0x1001)
Validity
Not Before: May 3 17:21:22 2026 GMT
Not After : May 3 17:21:22 2027 GMT
Subject:
countryName = JP
stateOrProvinceName = Tokyo
organizationName = MyOrg CA
commonName = client01
X509v3 extensions:
X509v3 Basic Constraints:
CA:FALSE
X509v3 Subject Key Identifier:
1E:27:C1:7B:1D:BF:5C:9E:12:33:28:1A:6A:B2:F6:1B:75:98:CF:9C
X509v3 Authority Key Identifier:
C0:56:7E:07:1C:41:84:27:2F:76:E2:62:0D:ED:94:89:9C:81:5B:9F
Certificate is to be certified until May 3 17:21:22 2027 GMT (365 days)
Write out database with 1 new entries
Data Base Updated
# 発行記録確認
cat /etc/ssl/myCA/index.txt
V 270503171633Z 1000 unknown /C=JP/ST=Tokyo/O=MyOrg CA/OU=Web/CN=www.example.com
V 270503172122Z 1001 unknown /C=JP/ST=Tokyo/O=MyOrg CA/CN=client01 # 追加されている
5. 証明書フォーマット変換(PEM / DER / PKCS)
概要
- PEM: Base64 エンコードされたテキスト形式。
-----BEGIN...-----ヘッダーを持つ。Linux 標準 - DER: バイナリ形式。Windows や Java でよく使われる
- PKCS#12 (.p12/.pfx): 秘密鍵と証明書をパスワード付きで1ファイルにまとめたバイナリ形式
- PKCS#7 (.p7b): 証明書チェーンの配布に使う(秘密鍵を含まない)
openssl x509,openssl pkcs12,openssl pkcs7でフォーマット変換を行う
5-1. PEM ↔ DER 変換
cd /root/pki-lab/server
# 証明書の中身を確認
head -2 server.crt
-----BEGIN CERTIFICATE-----
MIIEiTCCAnGgAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwaDELMAkGA1UEBhMCSlAx
# PEM → DERへの変換
openssl x509 \
-in server.crt \
-outform DER \
-out server.der
# DER → PEMへの変換
openssl x509 \
-in server.der \
-inform DER \
-outform PEM \
-out server-from-der.crt
# fileコマンドで証明書の形式を確認
file server.crt server.der server-from-der.crt
server.crt: PEM certificate
server.der: Certificate, Version=3 # DER
server-from-der.crt: PEM certificate
5-2. PKCS#12 (.p12) への変換
# PEM(証明書 + 秘密鍵 + CA証明書)→ PKCS#12への変換
openssl pkcs12 -export \
-in server.crt \
-inkey server.key \
-certfile /etc/ssl/myCA/cacert.pem \
-out server.p12 \
-passout pass:changeme
# PKCS#12 の内容確認
openssl pkcs12 -in server.p12 -noout -info -passin pass:changeme
MAC: sha256, Iteration 2048
MAC length: 32, salt length: 8
PKCS7 Encrypted data: PBES2, PBKDF2, AES-256-CBC, Iteration 2048, PRF hmacWithSHA256
Certificate bag
Certificate bag
PKCS7 Data
Shrouded Keybag: PBES2, PBKDF2, AES-256-CBC, Iteration 2048, PRF hmacWithSHA256
PKCS#12 から PEM へ展開
# 証明書のみ取り出す
openssl pkcs12 -in server.p12 \
-nokeys -out certs-only.pem \
-passin pass:changeme
# 秘密鍵のみ取り出す(パスフレーズなし)
openssl pkcs12 -in server.p12 \
-nocerts -nodes -out key-only.pem \
-passin pass:changeme
5-3. PKCS#7 (.p7b) への変換
# PEM 証明書 → PKCS#7への変換
openssl crl2pkcs7 -nocrl \
-certfile server.crt \
-certfile /etc/ssl/myCA/cacert.pem \
-out chain.p7b
# PKCS#7 → PEMへの変換
openssl pkcs7 -in chain.p7b -print_certs -out chain.pem
確認ポイント
- PEM と DER の違い(テキスト vs バイナリ)を確認した
-
openssl pkcs12 -exportで PKCS#12 を作成できた - PKCS#12 から証明書と秘密鍵を個別に取り出せた
- PKCS#7 で証明書チェーンをまとめられた
6. 証明書の失効(CRL)
概要
- CRL(Certificate Revocation List)は失効した証明書のシリアル番号一覧
openssl ca -revokeで証明書を失効させ、openssl ca -gencrlで CRL を生成する- CRL は定期的に再生成・公開する必要がある(有効期限あり)
- クライアントは接続前に CRL を取得して証明書の有効性を確認する
- 設定ファイルの
[ CA_default ]セクションのcrl_extensionsとdefault_crl_daysで制御する
6-1. 証明書の失効
cd /etc/ssl/myCA
# クライアント用の証明書を失効させる
openssl ca \
-config openssl.cnf \
-revoke /root/pki-lab/client/client.crt
# index.txt で失効状態を確認(R: Revoked が付く)
cat /etc/ssl/myCA/index.txt
V 270503171633Z 1000 unknown /C=JP/ST=Tokyo/O=MyOrg CA/OU=Web/CN=www.example.com
R 270503172122Z 260503173831Z 1001 unknown /C=JP/ST=Tokyo/O=MyOrg CA/CN=client01
6-2. CRL の生成と確認
# CRL を生成する
openssl ca \
-config openssl.cnf \
-gencrl \
-out crl/myCA.crl
Using configuration from openssl.cnf
# 失効シリアル番号が含まれていることを確認
openssl crl -in crl/myCA.crl -noout -text | grep -A 5 "Revoked"
Revoked Certificates:
Serial Number: 1001
Revocation Date: May 3 17:38:31 2026 GMT
Signature Algorithm: sha256WithRSAEncryption
Signature Value:
24:ce:e5:63:5d:af:64:1d:76:41:f0:aa:cd:5a:2b:f4:78:cf:
CRL を使った証明書検証
# CA 証明書と CRL を連結して検証
cat /etc/ssl/myCA/cacert.pem /etc/ssl/myCA/crl/myCA.crl > /tmp/chain-with-crl.pem
# CRLでクライアント用の証明書の検証
openssl verify \
-CAfile /tmp/chain-with-crl.pem \
-crl_check \
/root/pki-lab/client/client.crt
C = JP, ST = Tokyo, O = MyOrg CA, CN = client01
error 23 at 0 depth lookup: certificate revoked
error /root/pki-lab/client/client.crt: verification failed # 失効済みであることの表示
7. OCSP(オンライン証明書状態プロトコル)
概要
- OCSP は証明書の失効状態をリアルタイムに問い合わせるプロトコル(CRL の代替)
openssl ocspコマンドでレスポンダー起動と問い合わせの両方が可能- OCSP レスポンダーは CA 証明書で署名した応答を返す
- CRL との違い:CRL はダウンロードして全件確認するが、OCSP は個別に問い合わせる
7-1. OCSP レスポンダーの起動
OCSP 署名用鍵と証明書の作成
cd /etc/ssl/myCA
# OCSP 用の鍵と CSR 生成
openssl genrsa -out private/ocsp.key 2048
openssl req -new \
-key private/ocsp.key \
-out /tmp/ocsp.csr \
-subj "/C=JP/ST=Tokyo/O=MyOrg/CN=OCSP Responder"
# OCSP 専用証明書の発行(extendedKeyUsage に OCSPSigning を設定)
openssl ca \
-config openssl.cnf \
-in /tmp/ocsp.csr \
-out certs/ocsp.crt \
-extensions v3_OCSP \
-days 365 \
-notext 2>/dev/null || \
openssl x509 -req \
-in /tmp/ocsp.csr \
-CA cacert.pem \
-CAkey private/cakey.pem \
-CAcreateserial \
-out certs/ocsp.crt \
-days 365 \
-extfile <(printf "[ext]\nextendedKeyUsage=OCSPSigning")
Certificate request self-signature ok
subject=C = JP, ST = Tokyo, O = MyOrg, CN = OCSP Responder
バックグラウンドでOCSP レスポンダーを起動
# ポート 2560 でOCSP レスポンダーを起動
openssl ocsp \
-index /etc/ssl/myCA/index.txt \
-CA /etc/ssl/myCA/cacert.pem \
-rkey /etc/ssl/myCA/private/cakey.pem \
-rsigner /etc/ssl/myCA/cacert.pem \
-port 2560 \
-text &
[1] 3296
root@pki-lab:/etc/ssl/myCA# ACCEPT 0.0.0.0:2560 PID=3296
ocsp: waiting for OCSP client connections...
OCSP_PID=$!
echo "OCSP Responder PID: $OCSP_PID"
OCSP Responder PID: 3296
7-2. OCSP による証明書状態の確認
# サーバ証明書の状態を OCSP で確認(有効)
openssl ocsp \
-CAfile /etc/ssl/myCA/cacert.pem \
-issuer /etc/ssl/myCA/cacert.pem \
-cert /root/pki-lab/server/server.crt \
-url http://127.0.0.1:2560 \
-resp_text 2>&1 | grep -E "Response verify|server.crt:"
<中略>
/root/pki-lab/server/server.crt: good
# 失効済みクライアント用の証明書の状態確認
openssl ocsp \
-CAfile /etc/ssl/myCA/cacert.pem \
-issuer /etc/ssl/myCA/cacert.pem \
-cert /root/pki-lab/client/client.crt \
-url http://127.0.0.1:2560 \
-resp_text 2>&1 | grep -E "Response verify|client.crt:"
<中略>
/root/pki-lab/client/client.crt: revoked
# OCSP レスポンダー停止
kill $OCSP_PID 2>/dev/null || true
8. まとめ・比較表
ツール・コマンド比較
| コマンド | サブコマンド | 主な用途 |
|---|---|---|
| openssl genrsa | — | RSA 秘密鍵の生成 |
| openssl ecparam | -genkey | EC 秘密鍵の生成 |
| openssl req | -new | CSR の生成 |
| openssl req | -x509 | 自己署名証明書の生成 |
| openssl ca | — | CSR への署名(CA として) |
| openssl ca | -revoke | 証明書の失効 |
| openssl ca | -gencrl | CRL の生成 |
| openssl x509 | -text | 証明書の内容確認 |
| openssl x509 | -outform DER | PEM → DER 変換 |
| openssl pkcs12 | -export | PKCS#12 の作成 |
| openssl pkcs12 | — | PKCS#12 の展開 |
| openssl verify | -crl_check | 証明書の検証(CRL含む) |
| openssl ocsp | — | OCSP 問い合わせ / レスポンダー |
失効確認方法の比較
| 方式 | 更新タイミング | リアルタイム | ファイルサイズ |
|---|---|---|---|
| CRL | 定期的(手動/定期実行) | 非リアルタイム | 失効数に比例して増大 |
| OCSP | 都度問い合わせ | リアルタイム | 固定(個別応答) |
後片付け
VM を停止・削除する
# ホストマシンで実行
vagrant halt
vagrant destroy -f
付録: よく使うコマンドまとめ
# === 鍵生成 ===
openssl genrsa -out key.pem 2048 # RSA 秘密鍵
openssl genrsa -aes256 -out key-enc.pem 2048 # 暗号化 RSA 秘密鍵
openssl ecparam -genkey -name prime256v1 -out ec.key # EC 鍵
# === CSR ===
openssl req -new -key key.pem -out csr.pem # CSR 生成
openssl req -in csr.pem -noout -text # CSR 確認
# === 証明書確認 ===
openssl x509 -in cert.pem -noout -text # 全内容表示
openssl x509 -in cert.pem -noout -dates # 有効期限
openssl x509 -in cert.pem -noout -subject -issuer # Subject/Issuer
openssl x509 -in cert.pem -noout -fingerprint -sha256 # フィンガープリント
# === CA 操作 ===
openssl req -x509 -new -key ca.key -days 3650 -out ca.crt # ルート CA 作成
openssl ca -config openssl.cnf -in csr.pem -out cert.pem # 証明書発行
openssl ca -config openssl.cnf -revoke cert.pem # 証明書失効
openssl ca -config openssl.cnf -gencrl -out ca.crl # CRL 生成
# === フォーマット変換 ===
openssl x509 -in cert.pem -outform DER -out cert.der # PEM→DER
openssl x509 -in cert.der -inform DER -outform PEM -out cert.pem # DER→PEM
openssl pkcs12 -export -in cert.pem -inkey key.pem -out bundle.p12 # PKCS#12 作成
openssl pkcs12 -in bundle.p12 -nokeys -out certs.pem # PKCS#12→PEM(証明書)
openssl pkcs12 -in bundle.p12 -nocerts -nodes -out key.pem # PKCS#12→PEM(鍵)
# === 検証 ===
openssl verify -CAfile ca.crt cert.pem # 証明書検証
openssl verify -CAfile chain.pem -crl_check cert.pem # CRL 検証
openssl crl -in ca.crl -noout -text # CRL 確認
# === OCSP ===
openssl ocsp -CAfile ca.crt -issuer ca.crt -cert cert.pem -url http://ocsp:2560 # OCSP 問い合わせ
openssl ocsp -index index.txt -CA ca.crt -rkey ca.key -rsigner ca.crt -port 2560 # レスポンダー起動