6.1. X.509証明書と公開鍵暗号基盤

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証明書にはいくつかのエンコードタイプがあるが、代表的なものにPEMDERがある。

  • PEM
    • DERをBase64でテキスト化したもの
    • サーバー証明書、中間証明書、および秘密キーを1つのファイル内に含めることができる
    • テキスト エディタで開くことができる(可読性がある)
    • OpenSSLデフォルトのファイル形式
  • DER
    • JavaベースのWebサーバーに使用される
    • Binary形式
  • PKCS#7
    • 証明書のみを保存する
    • 秘密キーは保存できない
    • RSA Security社が定めた暗号化標準
  • PKCS#10
  • PKCS#12
    • Windowsプラットフォームで使用される
    • サーバー証明書、中間証明書、および秘密キーをパスワードで保護された単一の.pfxファイル内に保存できる

また、それぞれの特徴を表にまとめると以下の通り。

フォーマットエンコードファイルフォーマット
PEMBase64 ASCII.crt、.pem、.cer、.key
DERBinary.der または .cer
PKCS#7Base64 ASCII
PKCS#12Binary.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 <サブコマンド> [オプション]
サブコマンド説明
caCAの管理
ciphers使用可能な暗号スイートを一覧表示
crlCRLの管理
dgstメッセージダイジェストの計算
genrsaRSA暗号方式の秘密鍵を生成
rsaRSA暗号方式の鍵管理
reqCSRの管理
rsautlRSAアルゴリズムを使用したメッセージの暗号化と復号
s_clientSSL/TLSプロトコルを使用し指定しサーバ接続
s_serverSSL/TLSプロトコルを使用しデータを受け取るサーバとして動作
verifyX.509証明書の検証
x509X.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.der

OpenSSLによる証明書の作成と操作

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.cer

OpenSSLによるトラブルシューティング

## セキュアなコネクションの確立
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を使用して証明書を作成するのは以下の手順の通り。

  1. CA(認証局)の作成
  2. CAの生成
  3. サーバ証明書の生成

まずは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が使用できる。