6.1. X.509証明書と公開鍵暗号基盤
6.1.1. X.509証明書とPKIの基礎概念
X.509証明書
X.509証明書は公開鍵基盤(PKI)の標準規格であるX.509により定義された公開鍵証明書のこと。
Webサービスやメールなどで、公開鍵の所有者を認証するために使用される。
X509証明書には以下情報を含む。
- 公開鍵(証明書の所有者のもの)
- 所有者情報(ドメイン名、組織名など)
- 発行者情報(認証局/CAの情報)
- 有効期間
- CA署名(認証局の秘密鍵によるデジタル署名)
PKI(公開鍵基盤)
PKIは異なるコンピュータシステム間の通信を保護するために使用されるシステムのこと。
公開鍵と、その公開鍵の持ち主が正当であることを保証する認証局(CA)から構成される。
信頼の連鎖(トラストチェーン)
トラストチェーンとは対象となる末端の証明書からブラウザやOSに予め組み込まれているルート証明書(Root CA)までの一連の証明書が連鎖している状態のこと。
ルートCAの下に中間CAが存在する階層構造が主流。これにより、末端の証明書の信頼性がルートCAまで遡って証明される。

証明書の透明性(CT)
CTはすべてのSSL/TLS証明書の発行を公開されたログに記録し監査可能にする仕組みのこと。
これにより、CAによる不正な証明書の発行を防ぎ、悪意のある証明書が使用されるリスクを減らします。
認証局(CA)
認証局(CA)は、公開鍵の信頼性を検証する信頼できる第三者機関のこと。
デジタル証明書として知られる電子文書の発行を通じて、それらを暗号キーにバインドする。 公開キーの信頼性を検証する信頼できる第三者機関と言える。
認証局には以下の役割がある。
- デジタル証明書の発行- 有効な証明書署名要求 (CSR) を精査し、デジタル証明書を発行する。
 
- 証明書の失効管理- 侵害された証明書を取り消す手続きを行い、その情報をCRLやOCSPを通じて公開する。
 
証明書署名要求(CSR)
証明書署名要求(CSR) は基本的に生成される公開キーであり、CA に送信して署名を受けることができるもの。
CAがCSRに署名すると、署名したCAによって信頼される証明書が生成される。
証明書の形式とエンコード
X.509証明書にはいくつかのエンコードタイプがあるが、代表的なものにPEMとDERがある。
- PEM- DERをBase64でテキスト化したもの
- サーバー証明書、中間証明書、および秘密キーを1つのファイル内に含めることができる
- テキスト エディタで開くことができる(可読性がある)
- OpenSSLデフォルトのファイル形式
 
- DER- JavaベースのWebサーバーに使用される
- Binary形式
 
- PKCS#7- 証明書のみを保存する
- 秘密キーは保存できない
- RSA Security社が定めた暗号化標準
 
- PKCS#10
- PKCS#12- Windowsプラットフォームで使用される
- サーバー証明書、中間証明書、および秘密キーをパスワードで保護された単一の.pfxファイル内に保存できる
 
また、それぞれの特徴を表にまとめると以下の通り。
| フォーマット | エンコード | ファイルフォーマット | 
|---|---|---|
| PEM | Base64 ASCII | .crt、.pem、.cer、.key | 
| DER | Binary | .der または .cer | 
| PKCS#7 | Base64 ASCII | |
| PKCS#12 | Binary | .pfx、 .p12 | 
証明書のライフサイクルと管理
証明書のライフサイクル
公開鍵証明書には、発行。使用、更新、破棄といったライフサイクルが存在する。
公開鍵基盤では証明書のライフサイクルを管理する仕組みがあり、認証局がそれを行う。

証明書の管理
CRL
CRLは認証局が執行させた電子証明書のリスト(証明書失効リスト)のこと。
利用者はCRLを定期的にDLすることで証明書の有効性を確認する。
OCSP
OCSPは電子証明書の失効を問い合わせるプロトコルのこと。
OCSPレスポンダと呼ばれるサーバにアクセスすることで証明書の有効性を確認する。
6.1.2. X.509証明書の詳細構造
X.509証明書のフィールド
| フィールド1 | フィールド2 | 説明 | 
|---|---|---|
| 署名前証明書(tbsCertificate) | 証明書の基本情報と公開鍵の情報 | |
| バージョン(version) | X.509証明書のバージョン X509v3では3(0x2) | |
| シリアル番号(serialNumber) | 証明書の識別番号 | |
| 署名(signature) | CAが証明書に署名する際のアルゴリズム | |
| 発行者(issuer) | CAの名前 | |
| 有効期間(validity) | 証明書の有効期間 | |
| サブジェクト(subject) | 証明書の所有者の名前 | |
| サブジェクト公開情報(subjectPublicKeyInfo) | 証明書所有者の公開鍵に関する情報 | |
| 証明書拡張(extentions) | 拡張領域。X.503v3にて追加 | |
| 署名アルゴリズム(signatureAlogorithm) | 証明書の署名アルゴリズム | |
| 署名値(signatureValue) | デジタル署名 | 
X.509v3証明書拡張
| 拡張フィールド | 説明 | 
|---|---|
| basicConstraints(基本制約) | 基本制約。証明書がCAのものである、証明書のパスの深さなどを指定 | 
| authorityKeyIdentifier(認証局鍵識別子) | 認証局鍵識別子 | 
| subjectKeyIdentifier(サブジェクト識別子) | サブジェクト識別子 | 
| KeyUsaga(鍵の用途) | 鍵の用途 | 
| extendedKeyUsage(拡張鍵用途) | 鍵の用途を限定 | 
| certificatePolicies(証明書ポリシ) | 証明書の目的や発行時情報 | 
| subjectAltName(所有者別名) | サブジェクトの代替名 | 
| cRLDistributionPoints(CRL配布ポイント) | CRLの配布ポイント | 
| authorityInfoAccess(機関情報アクセス) | 認証局に関する追加情報へアクセス | 
6.1.3. OpenSSLによる鍵とCAの操作
OpenSSLの概要
SSL/TLSの実装としてのツールにOpenSSLがある。 OpenSSLの機能は以下の通り。
- 秘密鍵/公開鍵の作成、パラメータ管理
- 公開鍵の暗号操作
- X.509証明書と証明書署名要求(CSR)/証明書失効リスト(CRL)の作成
- メッセージダイジェストの計算
- RSA暗号方式による暗号化と復号
- SSL/TLSクライアントとサーバテスト
- S/MIME署名と暗号化メールの取り扱い
- タイムスタンプの要求/生成、検証
opensslの設定ファイル
openSSLの設定ファイルは以下の通り。
- Debian系 … /usr/lib/ssl/openssl.cnf
- RedHat系 … /etc/pki/tls/openssl.cnf
opensslコマンド
OpenSSLの操作を行うコマンド。
openssl <サブコマンド> [オプション]| サブコマンド | 説明 | 
|---|---|
| ca | CAの管理 | 
| ciphers | 使用可能な暗号スイートを一覧表示 | 
| crl | CRLの管理 | 
| dgst | メッセージダイジェストの計算 | 
| genrsa | RSA暗号方式の秘密鍵を生成 | 
| rsa | RSA暗号方式の鍵管理 | 
| req | CSRの管理 | 
| rsautl | RSAアルゴリズムを使用したメッセージの暗号化と復号 | 
| s_client | SSL/TLSプロトコルを使用し指定しサーバ接続 | 
| s_server | SSL/TLSプロトコルを使用しデータを受け取るサーバとして動作 | 
| verify | X.509証明書の検証 | 
| x509 | X.509証明書の管理 | 
OpenSSLによる鍵の生成と管理
# 設定ファイルの確認
openssl ca
# openssl genrsa はRSA秘密鍵の生成を行う
# 秘密鍵の作成(TripleDES方式で暗号化したRSA形式の秘密鍵を2048bitで作成)
openssl genrsa -out private.key -des3 2048
openssl genrsa -des3 2048 > /etc/pki/CA/private/cakey.pem
# 秘密鍵の作成
openssl genrsa -<algorithm> -out <key_filename> <key_size>
openssl genrsa -aes128 -out mykey.key 2048
# openssl rsa は秘密鍵の管理を行う
# 暗号化された秘密鍵を暗号化解除したファイルの変換する
openssl rsa -in private.key -out private-nopass.key
# 秘密鍵から公開鍵を作成する
openssl rsa -in private.key -pubout -out publkey.key
# RSA形式の秘密鍵の内容を確認する
openssl rsa -in private.key -text
# RSA形式の公開鍵の内容を確認する
openssl rsa -publin -in pubkey.key -text
# openssl rsautl はRSAを利用したデータの暗号化/復号化を行う
# 公開鍵を用いたテキストの暗号化
openssl rsautl -encrypt -pubin -inkey pubkey.key -in sample.txt -out sample.txt.enc
# 秘密鍵を用いてテキストの復号
openssl rsautl -decrypt -inkey private.key -in sample.txt.enc -out sample.key
# openssl req はCSRを生成する
# 公開鍵の作成
openssl req -utf8 -new -key <key_filename> -x509 -days <cert-lifespan> -out <cert_filename> -set_serial 0
# X.509形式のCSRの新規作成
openssl req -new -key <priv_key.pem> -out <output.csr>
# openssl ca は認証局の証明書を管理する
# サーバ証明書の発行
openssl ca -out newcert.pem -days 365 -keyfile private.pem -infiles newcsr.pem
# 証明書の失効
openssl ca -revoke newcert.pem
# CSRにCAとして署名する
openssl ca -in <CSR> -out <crt>
# 証明書情報の確認
openssl x509 -in <cert_filename.crt> -text -nout | less
# PEM形式の証明書をDER形式に変換する
openssl x509 -inform PEM -outform DER -in newcert.pem -out newcert.derOpenSSLによる証明書の作成と操作
opensslコマンドにより秘密鍵/証明書などを作成できる。
使用例は以下の通り。
# 秘密鍵の生成
openssl genrsa -<algorithm> -out <key_filename> <key_size>
openssl genrsa -aes128 -out mykey.pem 2048
# 自己証明書(オレオレ認証)の生成
openssl req -utf8 -new -key <key_filename> -x509 -days <cert_lifespan> -out <cert_filename>
#認証の表示
openssl x509 -in mycert.crt -text -noout
#CSR(証明書失効リスト)の作成
openssl req -new -key <priv_key.pem> -out <output.csr>OpenSSLによるX.509証明書形式の変換/検証
#DERをPEMに変換する
openssl x509 -inform der -in certificate.cer -out certificate.pem
#PEMをDERに変換する
openssl x509 -outform der -in certificate.pem -out certificate.der
#p7b/pkcs#7をPEMに変換する
openssl pkcs7 -print_certs -in certificate.p7b -out certificate.pem.
#PEMをp7b/pkcs#7に変換する
openssl pkcs7 -print_certs -in certificate.p7b -out certificate.cerOpenSSLによるトラブルシューティング
## セキュアなコネクションの確立
openssl s_client -connect <host>:<port> 
## トラストチェーンの検証 
openssl verify -verbose <certificate> 
## CAチェーンのすべての証明書を確認する
openssl s_client -connect <host>:<port> -showcerts
## 証明書の詳細を見る
openssl x509 —text <cert_file> 6.1.4. 現代の証明書管理技術
Let’s Encrypt/ACME/Certbot
Let’s Encrypt
Let’s EncryptとはX.509証明書を無料で発行している認証局(CA)のこと。
すべてのWebサイトの暗号化を目指す非営利団体ISRG(Internet Security Research Group)によって運営されている。
SSLサーバ証明書の種類
SSLサーバ証明書には認証する内容によっていくつかの種類がある。
- DV(Domain Validation:ドメイン認証)- ドメイン名の所有者であることを証明する
 
- OV(Organization Validation:企業認証)- ドメイン名の所有者であること、ドメイン名に登録されている企業が法的に実在していることを証明する
 
- EV(Extended Validation:拡張検証)- ドメイン名の所有者であること、ドメイン名に登録されている企業が物理的・法的に実在していることを証明する(電話による在籍確認など、OVよりも厳しい審査が行われる)
 
このうちLet’s Encryptが発行しているのはDVタイプのサーバ証明書となる。
ACME
ACME(Automatic Certificate Management Environment:自動証明書管理環境)は、Let’s Encryptが証明書の発行と管理を自動化するために用いている標準化されたプロトコルである。
- 役割- 証明書の発行に必要な鍵の作成、CSRの作成とCAへの送信、証明書の設定や更新などの手続きを完全に自動化する。
 
- 仕組み- ACMEクライアントとCA(Let’s Encrypt)が安全に通信し、ドメインの所有権を自動で検証(チャレンジ)する。
 
Certbot
Certbotは、Let’s Encryptが推奨する主要なACMEクライアントである。
- 機能- ACMEプロトコルを使用して、Webサーバー(Apache, Nginxなど)に対する証明書の取得、インストール、そして有効期限が切れる前の自動更新を一元的に行う。
 
- 利点- 複雑なOpenSSLコマンドやWebサーバー設定の手動編集を大幅に削減し、証明書運用を容易にする。
 
CFSSL
CFSSLはOpenSSLよりも簡単に証明書や認証局を作成できるコマンドでCloudFlareが公開している。
JSON形式の設定ファイルを用いて一連の作業を自動化し、証明書管理を簡素化が可能。
CFSSLの使い方
CFSSLを使用して証明書を作成するのは以下の手順の通り。
- CA(認証局)の作成
- CAの生成
- サーバ証明書の生成
まずはCAの作成のためCAの設定ファイルとCSRをjsonで作成する。
{
    "signing": {
        "default": {
        "expiry": "8760h"
        },
        "profiles": {
        "server": {
            "usages": [
            "signing",
            "key encipherment",
            "server auth"
            ],
            "expiry": "8760h"
        },
            "client": {
                "usages": [
                "signing",
                "key encipherment",
                "client auth"
                ],
                "expiry": "8760h"
            }
        }
    }
}{
    "CN": "My CA",
    "key": {
        "algo": "rsa",
        "size": 2048
    },
    "names": [
        {
        "C": "JP",
        "L": "Tokyo",
        "O": "My Company",
        "OU": "My CA Unit",
        "ST": "Tokyo"
        }
    ]
}設定ファイルと署名要求ファイルができたら、cfsslとcfssljsonコマンドを組み合わせてCAの鍵と証明書を生成する。
cfssl genkey -initca ca-csr.json | cfssljson -bare caこのコマンドを実行すると、ca.pem(CA証明書)、ca-key.pem(CA秘密鍵)、ca.csr(CAのCSR)が生成される。
次に作成したCAを使ってサーバー証明書を発行する。
server-csr.json
{
  "CN": "example.com",
  "hosts": [
    "example.com",
    "www.example.com",
    "127.0.0.1"
  ],
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "JP",
      "L": "Tokyo",
      "O": "My Company",
      "OU": "Web Server",
      "ST": "Tokyo"
    }
  ]
}CAの秘密鍵と証明書、そしてサーバー証明書のCSRを使って、サーバー証明書を生成する。
cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=server server-csr.json | cfssljson -bare serverこのコマンドを実行すると、server.pem(サーバー証明書)とserver-key.pem(サーバーの秘密鍵)が生成される。
genkey
genkeyはOpensslの互換ツールでRedHat系OSで使用できるもの。
コマンドはOpenSSLより単純で、TUIが使用できる。