はじめに

本記事では、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_extensionsdefault_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 # レスポンダー起動