2 tierプライベート認証局を作る

(2015.7.20)

Root CA, Issuing CAを分離したオレオレ認証局 (CA) を作ります。そのうえで、クライアント証明書、サーバ証明書を作ってみます。

用語

認証局 / Certification Authority (CA). Certificate Authorityとも。
デジタル証明書を発行する。認証局のうちルート認証局 (Root Certification Authority) は、PKI hierarchy の頂点の認証局で、すべての参加者から無条件で信用される (ようになっている)。
Issuing CA
中間CA (Intermediate CA) のうち, エンドユーザとコンピュータに対する証明書を発行する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:

信頼の輪

認証局は、証明書を発行したり、下位の認証局の信頼性を保証したり (Root CAの場合) します。

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

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

Create your own Chain of Trust | BlubGoo

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

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

今回は、ルートCA, 中間CA, サーバ証明書を作ってみます。

参考:

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

openssl パッケージに, openssl コマンドのサンプルとして, /etc/pki/tls/misc/CA スクリプトが含まれます。

オプションを与えないと, /etc/pki/tls/openssl.cnf ファイルが設定として使われます。

SSLEAY_CONFIG環境変数に自分の設定ファイルを与えて、挙動を変えます。ものすごく分かりにくい。

CAスクリプトのコマンド一覧

-newcert

新たに秘密鍵と自己署名証明書を作る.

次のコマンドと同じ;

$OPENSSL req $SSLEAY_CONFIG -new -x509 -keyout newkey.pem -out newcert.pem $DAYS

$SSLEAY_CONFIG で設定を与えればいい。newkey.pem は秘密鍵、newcert.pem は証明書。

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

X509v3 Basic Constraints:
    CA:TRUE

何でもありのオレオレ証明書で、実験用などのために使われる。本番では使えない。

-newreq

新たに秘密鍵と証明書署名要求 (certificate signing request; CSR) を作る.

$OPENSSL req $SSLEAY_CONFIG -new -keyout newkey.pem -out newreq.pem $DAYS

-newreq-nodes

証明書署名要求を作る。-newreq と違い, 秘密鍵とリクエストが newreq.pem に入る。

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

-newca

新しいCAを作る.

内部では、2 steps で、自分あての証明書署名要求とそれに基づく証明書が作られる。

$REQ -new -keyout ${CATOP}/private/$CAKEY \
     -out ${CATOP}/$CAREQ
$CA -create_serial -out ${CATOP}/$CACERT $CADAYS -batch \
    -keyfile ${CATOP}/private/$CAKEY -selfsign \
    -extensions v3_ca \
    -infiles ${CATOP}/$CAREQ

-newcertコマンドと違い, カレントディレクトリがどこであろうと, /etc/pki/CA/newcerts/ 以下に PEM ファイルが作られる.

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

-pkcs12

証明書と秘密鍵から, PKCS#12 形式のファイル (.p12/.pfx) を生成する。

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

$PKCS12 -in newcert.pem -inkey newreq.pem -certfile ${CATOP}/$CACERT \
        -out newcert.p12 -export -name "$CNAME"

-sign | -signreq

証明書署名要求に対して, 署名して証明書を作成する。

$OPENSSL ca $SSLEAY_CONFIG -policy policy_anything -out newcert.pem -infiles newreq.pem

opensslコマンドの -keyfile オプションが指定されていないため、CA の秘密鍵の場所は、設定ファイルで指定する。

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

-signCA

opensslコマンドに渡すオプションがちょっと違う。

$OPENSSL ca $SSLEAY_CONFIG -policy policy_anything -out newcert.pem -extensions v3_ca -infiles newreq.pem

-verify

証明書を検証する.

$OPENSSL verify -CAfile $CATOP/$CACERT newcert.pem

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

$ /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.

ルートCAの自己署名証明書を作る

まず、ルートCAの自己署名証明書から。

環境: Fedora 22 Linux (192.168.0.9)

root になって、適当な場所でCAスクリプトを走らせます。

~# /etc/pki/tls/misc/CA -newca
CA certificate filename (or enter to create)  上位CAがあれば指定

Making CA certificate ...
Generating a 2048 bit RSA private key
..................................................................+++
..................................+++
writing new private key to '/etc/pki/CA/private/./cakey.pem'
Enter PEM pass phrase:   秘密鍵のパスフレーズを決める
Verifying - Enter PEM pass phrase:  再入力
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:JP
State or Province Name (full name) []:FUKUOKA
Locality Name (eg, city) [Default City]:Munakata
Organization Name (eg, company) [Default Company Ltd]:Netsphere Laboratories
Organizational Unit Name (eg, section) []:         OU は空で構わない
Common Name (eg, your name or your server's hostname) []:Netsphere Laboratories Root CA  CNが証明書ストアなどに表示される。"Root CA"などを含めて、見分けやすいようにする。
Email Address []:hisashi.horikawa@gmail.com

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
Using configuration from /etc/pki/tls/openssl.cnf
Enter pass phrase for /etc/pki/CA/private/./cakey.pem:  先ほど決めた, 秘密鍵のパスフレーズ
Check that the request matches the signature
Signature ok     秘密鍵で署名し、証明書を作成
Certificate Details:
    以降、今作ったRoot CAの情報が表示される.

実行前のディレクトリ

# find /etc/pki/CA/
/etc/pki/CA/
/etc/pki/CA/private
/etc/pki/CA/certs
/etc/pki/CA/crl
/etc/pki/CA/newcerts

実行後は、次のようにファイルが生成されています。

# find /etc/pki/CA
/etc/pki/CA
/etc/pki/CA/private
/etc/pki/CA/private/cakey.pem   Root CAの秘密鍵
/etc/pki/CA/careq.pem
/etc/pki/CA/certs
/etc/pki/CA/cacert.pem     Root CAの証明書
/etc/pki/CA/index.txt.attr
/etc/pki/CA/serial
/etc/pki/CA/crl
/etc/pki/CA/index.txt.old
/etc/pki/CA/index.txt
/etc/pki/CA/newcerts
/etc/pki/CA/newcerts/A38D896E37349F44.pem

証明書の内容を表示するには、次のようにします。一般ユーザでも表示できます。

$ openssl x509 -in /etc/pki/CA/cacert.pem -text

中間CAを作る

中間CAのための鍵ペア (公開鍵と秘密鍵) を作り、公開鍵は先ほどのルート認証局に署名してもらい、証明書を作る。

中間CAからさらにCAを作れないように, CA:TRUE, pathlen = 0にします。

この文書の 4.2.1.9. Basic Constraints にあります。

まず秘密鍵を作ります。

intermediate-ca$ openssl genrsa 2048 > my_intermediate_ca.private.pem
Generating RSA private key, 2048 bit long modulus
....................................+++
......................+++
e is 65537 (0x10001)

このファイルは「-----BEGIN RSA PRIVATE KEY-----」で始まるテキストファイルです。(PEM形式)

Web上には非常に混乱した解説が多くありますが、PEM形式は単に「-----BEGIN ラベル-----」で始まり「-----END ラベル-----」で終わるテキストファイルのファイル形式です。その内容は, べつに秘密鍵に限定されず, ラベルで決まります。

秘密鍵の内容を表示するには, 次のようにします。

$ openssl rsa -text < my_intermediate_ca.private.pem
Private-Key: (2048 bit)
modulus:
    00: 以下略
publicExponent: 略
privateExponent:
    60: 以下略
素数が続く

秘密鍵から公開鍵を作るのは、こうします;

intermediate-ca$ openssl rsa -pubout < my_intermediate_ca.private.pem

署名要求 (CSR) を作る

秘密鍵から公開鍵を作り、Root CAに対して, その公開鍵に署名してもらうための署名要求 (CSR) を作る.

ここで入力するのは、中間CAの情報。

~/my-ca$ openssl req -new -key my_intermediate_ca.private.pem > my_intermediate_ca.csr.pem
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:JP
State or Province Name (full name) []:FUKUOKA
Locality Name (eg, city) [Default City]:Munakata
Organization Name (eg, company) [Default Company Ltd]:Netsphere Laboratories
Organizational Unit Name (eg, section) []:
Common Name (eg, your name or your server's hostname) []:Netsphere Laboratories Intermediate CA
Email Address []:hisashi.horikawa@gmail.com

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:

CSRは「-----BEGIN CERTIFICATE REQUEST-----」で始まります。

内容の表示はこうします。公開鍵だけが含まれます。

$ openssl req -text < my_intermediate_ca.csr.pem
Certificate Request:
    Data:
        Version: 0 (0x0)
        Subject: C=JP, ST=FUKUOKA, L=Munakata, O=Netsphere Laboratories, CN=Netsphere Laboratories Intermediate CA/emailAddress=hisashi.horikawa@gmail.com
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (2048 bit)
                Modulus:
                    00: 以下略

別解: 秘密鍵とCSRを同時に作る

先ほどは秘密鍵から署名要求を作ったが、何もないところから, 秘密鍵を作るのと同時にCSRを作るやり方;

~/my-ca$ /etc/pki/tls/misc/CA -newreq
Generating a 2048 bit RSA private key
.................................................................+++
......+++
writing new private key to 'newkey.pem'
Enter PEM pass phrase:           秘密鍵のパスフレーズを決める
Verifying - Enter PEM pass phrase:
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:JP
State or Province Name (full name) []:FUKUOKA
Locality Name (eg, city) [Default City]:Munakata
Organization Name (eg, company) [Default Company Ltd]:Netsphere Laboratories
Organizational Unit Name (eg, section) []:
Common Name (eg, your name or your server's hostname) []:Netsphere Laboratories Intermediate CA 2
Email Address []:hisashi.horikawa@gmail.com

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
Request is in newreq.pem, private key is in newkey.pem

この方法では、カレントディレクトリにパスワード保護された秘密鍵 newkey.pem と署名要求 newreq.pem ができる。

Root CAで署名

ルートCAの秘密鍵で, 中間CAからの署名要求に署名し、証明書を作る。

/etc/pki/tls/openssl.cnf をコピーして修正する。変更は[ v3_ca ]セクションだけで大丈夫。

[ v3_ca ]

# ここを修正。
basicConstraints = CA:true, pathlen:0

# ここのコメントアウトを外す
keyUsage = cRLSign, keyCertSign

# ここのコメントアウトも外す
nsCertType = sslCA, emailCA

Unix rootになって、CAスクリプトを走らせる。ここでは-signCAを使う。

root-ca# SSLEAY_CONFIG="-config cert-for-intermediate-ca.cnf" /etc/pki/tls/misc/CA -signCA
Using configuration from cert-for-intermediate-ca.cnf
Enter pass phrase for /etc/pki/CA/private/cakey.pem:     Root CAのパスワード
Check that the request matches the signature
Signature ok
Certificate Details:
        Serial Number: 略
ここで、中間CAの情報が表示される。
            X509v3 Basic Constraints: 
                CA:TRUE, pathlen:0
            X509v3 Key Usage: 
                Certificate Sign, CRL Sign
            Netscape Cert Type: 
                SSL CA, S/MIME CA
Certificate is to be certified until Jul 25 10:05:52 2016 GMT (365 days)
Sign the certificate? [y/n]:y


1 out of 1 certificate requests certified, commit? [y/n]y
Write out database with 1 new entries
Data Base Updated
Signed CA certificate is in newcert.pem

なお、Netscape Cert Type (nsCertType) は 非推奨 (deprecated) であり、basicConstraints, keyUsage, Extended Key Usage (extendedKeyUsage) で代替されている。

カレントディレクトリに中間CAの証明書 newcert.pem が作成される。

内容を見るのは、こう;

~/my-ca$ openssl x509 -in newcert.pem -text

次回へ続く。