PKI: CA階層, 2/3 tierと基礎

(2018.2) ページが長くなったので分割。

実際にルートCA, 中間CAを作ったりするのはこちら; 2 tierプライベート認証局を作る

CA hierarchy

公開鍵基盤 (PKI) は, 認証局をツリー状に考えて, 頂点の Root CA から「信頼の輪」を繋いでいきます。

用語

認証局 / Certification Authority (CA). Certificate Authorityとも。
認証局は, デジタル証明書を発行する。認証局のうちルート認証局 (Root Certification Authority) は, CA hierarchy の頂点の認証局で、すべての参加者から無条件で信用される (ようになっている)。
Issuing CA
中間CA (Intermediate CA) は, Root CA以外の認証局。そのうち, エンドユーザとコンピュータに対する証明書を発行するCA が Issuing CA. 今回の例では, 中間CAは1段階しか置かないので、特に区別しない。
デジタル証明書
証明したい公開鍵に対して、認証局の秘密鍵で署名したもの。

Root CAとIssuing CAの分離

Root CAとIssuing CAを分離すると、Issuing CAにセキュリティ上の欠陥があっても、そこだけ対処すればよい。

CAを2段にする "2 tier" CA Hierarchy と "3 tier" がある。

Infrastructure Saturday 2011 - Understanding PKI and Certificate Services

2 Tier CA Hierarchy:

3 Tier CA Hierarchy:

信頼の輪

認証局は、証明書を発行したり、下位の認証局の信頼性を保証したり, ソフトウェア (プログラム) が改竄されていないことを保証したりします。いずれも、対象物に対して、認証局の秘密鍵で署名 (sign) することです。

正しい証明書 (certificate) は、信頼させたい公開鍵 (public key) に対して, 信頼できる認証局が自身の秘密鍵によって署名 (sign) したものです。ルート認証局の発行する「ルート証明書」は、特別に、ルート認証局の公開鍵を自身の秘密鍵で署名しています -- 自己署名証明書。

ルートCAの証明書、中間CAの証明書、目的の証明書、と段数が増えても、順にルート証明書に向かってたどることで、信頼できるか確認 (検証; verify) できます。

https://www.blubgoo.com/create-your-own-chain-of-trust/ [リンク切れ]

一方, オレオレ認証局は、信頼できない認証局です。「信頼できない」とは、信頼できるルート認証局まで信頼の輪 (Chain of Trust) をつなげることができない認証局です。

オレオレ認証局が発行する証明書は,「オレオレ証明書」と呼ばれたりします。その証明書を受け取った人は、検証 (認証パスを辿ること) ができません。

まぁ、現実世界ではたまに, ルート認証局がその運用の不備などによって「信頼できない」となって、大騒ぎになったりしますが。

ルート証明書ストア

(2018.2) この節追加.

Fedora 26 Linux だと, ca-certificates パッケージに, ルート証明書のファイルがあります。

man 8 update-ca-trust で、内容の説明があります。

/etc/pki/ca-trust/extracted/ 以下に、ルート証明書が格納されています.

  • java/cacerts -- Java Keystore (JKS) 形式.
  • openssl/ca-bundle.trust.crt -- BEGIN/END TRUSTED CERTIFICATE ファイル形式.
  • pem/objsign-ca-bundle.pem -- code signing.
  • pem/tls-ca-bundle.pem -- TLSサーバ認証用.
  • pem/email-ca-bundle.pem -- e-mail protection.

過去との互換性のため, シンボリックリンクが張られています.

/etc/ssl/certs/ は, /etc/pki/tls/certs/ へのシンボリックリンクです。/etc/ssl/ はもはや古いです。

/etc/pki/ 以下も, シンボリックリンクで互換性を取っています. これらを使って構いません。

ファイル名 実体
tls/certs/ca-bundle.crt ca-trust/extracted/pem/tls-ca-bundle.pem
tls/certs/ca-bundle.trust.crt ca-trust/extracted/openssl/ca-bundle.trust.crt
java/cacerts ca-trust/extracted/java/cacerts
tls/cert.pem ca-trust/extracted/pem/tls-ca-bundle.pem これはもはや古い.
●Windows => mmcを使う.

/etc/pki/tls/misc/CA スクリプト

(2018.2) /etc/pki/tls/misc/CA というファイルは, もはやありません. Fedora 26 Linux では, openssl-perl パッケージに分離され, /usr/bin/CA.pl に移動しました。コマンドの挙動は最新のものに更新しました。

オプションを与えないと, /etc/pki/tls/openssl.cnf ファイルが設定として使われます。 そうでもない。CA.pl にデフォルト値がハードコードされている。

SSLEAY_CONFIG環境変数 名前が変わった. "OPENSSL_CONFIG"環境変数に自分の設定ファイルを与えて、挙動を変えます。ものすごく分かりにくい。

CA.plスクリプトのコマンド一覧を示す。詳しくは man 1 CA.pl

認証する側で使うコマンド

-newcert コマンド -- create a certificate
新たに秘密鍵と自己署名証明書を作る. 対話式に, Country Name, Organization Name, etc. を入力していく。

次のコマンドと同じ;

$OPENSSL req $OPENSSL_CONFIG -new -x509 -keyout newkey.pem -out newcert.pem \
             -days 365

カレントディレクトリに作られる。newkey.pem は秘密鍵、newcert.pem は証明書。

できあがる証明書は次のようになっており、Root CAになる。

X509v3 Basic Constraints: critical
    CA:TRUE

オプションを何も与えないと, 何でもありの証明書で、実験用に使うようなものになる。本番では使えない。

-newca コマンド -- create a new CA hierarchy.
新しいCAを作る. 既存の秘密鍵と証明書があればそれを使い、なければ新規に作る。

新規に作る場合は, 内部では、2 steps で、自分あての証明書署名要求とそれに対する署名で, 証明書が作られる。

$OPENSSL req $OPENSSL_CONFIG -new -keyout ${CATOP}/private/cakey.pem \
             -out ${CATOP}/careq.pem
$OPENSSL ca $OPENSSL_CONFIG -create_serial -out ${CATOP}/cacert.pem -days 1095 \
            -batch \
            -keyfile ${CATOP}/private/cakey.pem -selfsign \
            -extensions v3_ca \
            -infiles ${CATOP}/careq.pem

ただし, {$CATOP}/etc/pki/CA.

最終的に /etc/pki/CA/ 以下に, 秘密鍵の PEM ファイル (private/cakey.pem) と証明書ファイル (cacert.pem) が作られる.

-extensions v3_ca オプションがミソで, /etc/pki/tls/openssl.cnf ファイルの [v3_ca] セクションの内容が利用される。

-sign コマンド
証明書署名要求 (CSR) に対して, 署名して証明書を作成する。
$OPENSSL ca $OPENSSL_CONFIG -policy policy_anything -out newcert.pem \
            -infiles newreq.pem

opensslコマンドの -keyfile オプションが指定されていないため、CA の秘密鍵の場所は OPENSSL_CONFIG 環境変数で指定する。

署名され, 生成された証明書が newcert.pem として出力される。

-signCA コマンド
opensslコマンドに渡すオプションがちょっと違う。
$OPENSSL ca $OPENSSL_CONFIG -policy policy_anything -out newcert.pem \
            -extensions v3_ca -infiles newreq.pem

-signcertコマンドは, 署名要求 (CSR) の代わりに, 自己署名証明書を用いるもの。意味ないので, 使うことはない.

要求側で使うコマンド

-newreq コマンド -- create a certificate request
新たに秘密鍵ファイルと, 証明書署名要求 (certificate signing request; CSR) を作る.
$OPENSSL req $OPENSSL_CONFIG -new -keyout newkey.pem -out newreq.pem -days 365
-newreq-nodes コマンド -- create a certificate request
新たに秘密鍵ファイル (newkey.pem) と, 証明書署名要求 (CSR) を作る。-newreq コマンドと違い, 秘密鍵のパスフレーズが設定されない。

次と同じ:

$OPENSSL req $OPENSSL_CONFIG -new -nodes -keyout newkey.pem -out newreq.pem \
             -days 365

クライアント証明書を作るときに使う。証明書をもらってから -pkcs12 コマンドと組み合わせる。

-pkcs12 コマンド -- create a PKCS#12 file containing the user certificate.
発行してもらった証明書と自分の秘密鍵から, PKCS#12 形式のファイル (.p12/.pfx) を生成する。

.pfxファイルは, クライアント認証のために, クライアント側に秘密鍵・証明書ペアをインストールするために用いられる。

コード署名 (code signing) するためにストアに格納しておくためにも、いったん .pfxファイルにする。

引数として証明書の名前を与える. 省略したときは "My Certificate".

$ CA.pl -pkcs12 証明書の名前     

次と同じ:

$OPENSSL pkcs12 -in newcert.pem -inkey newkey.pem -certfile ${CATOP}/cacert.pem \
        -out newcert.p12 -export -name "$CNAME"

OPENSSL_CONFIG 環境変数は参照しない。

-crl コマンド
TODO: 追加。●●
$OPENSSL ca $OPENSSL_CONFIG -gencrl -out ${CATOP}/crl/crl.pem
-revoke <certfile> コマンド
TODO: 追加。●●

利用者が使うコマンド

-verify コマンド
証明書を検証する. 引数を省略したときは newcert.pem を, 引数を与えたときはそれらのファイルを順次検証する.

次と同じ:

$OPENSSL verify -CAfile ${CATOP}/cacert.pem $file

OPENSSL_CONFIG 環境変数は参照しない。

試しに、先ほど作った自己署名証明書を検証してみる;

$ /etc/pki/tls/misc/CA -verify newcert.pem
newcert.pem: C = XX, L = Default City, O = Default Company Ltd
error 18 at 0 depth lookup:self signed certificate
OK

error 18 ... X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT: self signed certificate.

keyUsage, extendedKeyUsage, nsCertType

(2018.2)

証明書は, 用途を限定するようにします。詳しくは man 5 x509v3_config

RFC 5280 Internet X.509 Public Key Infrastructure Certificate and Certificate Revocation List (CRL) Profile

keyUsage

次のうち一つ以上を指定;

CA (Root CA, 中間CAいずれも) は, この値は critical にすること。CAは, digitalSignature, keyCertSign, cRLSign. 逆に, CA 以外では keyCertSign または cRLSign は含めてはいけない.

bit
digitalSignature 0
nonRepudiation 1
keyEncipherment 2
dataEncipherment 3
keyAgreement 4
keyCertSign 5
cRLSign 6
encipherOnly 7
decipherOnly 8

extendedKeyUsage

目的 (purpose) を記載. CA では指定しない。●そうでもないなー●●

Value Meaning
serverAuth SSL/TLS Web Server Authentication.
clientAuth SSL/TLS Web Client Authentication.
codeSigning Code signing.
emailProtection E-mail Protection (S/MIME).
timeStamping Trusted Timestamping
OCSPSigning OCSP Signing ここまでRFC 5280
ipsecIKE ipsec Internet Key Exchange 1.3.6.1.5.5.7.3.17 RFC 4945
msCodeInd Microsoft / Software Publishing / Individual Code Signing (authenticode) 1.3.6.1.4.1.311.2.1.21
msCodeCom Microsoft / Software Publishing / Commercial Code Signing (authenticode) 1.3.6.1.4.1.311.2.1.22
msCTLSign Microsoft / Crypto 2.0 / Trust List Signing 1.3.6.1.4.1.311.10.3.1
msEFS Microsoft / Crypto 2.0 / Encrypted File System 1.3.6.1.4.1.311.10.3.4

See Object IDs associated with Microsoft cryptography

nsCertType

もはや古い. 使わない.

Netscape Cert Type (nsCertType) は, basicConstraints, keyUsage, Extended Key Usage (extendedKeyUsage) で代替されている。

取れる値:

client, server, email, objsign, reserved, sslCA, emailCA, objCA