OpenSSLでオレオレ認証局を作ろう
フリーなSSLの実装であるOpenSSLがこの世に登場してから15年以上の月日が経過しています。したがって、OpenSSLを使用したオレオレ認証局の構築手順を紹介しているサイトは多数あります。しかし、各操作の意味まで説明しているサイトは、残念ながらほとんど見当たりません。本稿では、オレオレ認証局の構築手順について、各操作の意味の説明を交えながら紹介しています。
(お断り)
本稿の内容は筆者がOpenSSLの公式文書、ソースコード、RFC (Request for Comments)、インターネット上の情報サイト、実機検証の結果などに基づいています。そのため、誤った内容を記載している場合がありますので、あらかじめご了承ください。
オレオレ認証局の構築
まず、オレオレ認証局を構築します。
準備
一般ユーザで構築するため、openssldirをホームディレクトリ直下にコピーします。Red Hat Enterprise Linuxの場合、openssldirは/etc/pki/tlsです。
$ cp -a /etc/pki/tls .
続いて、openssl.cnfを開き、CA_defaultセクションのdirを「./」に設定します。元々は、「./demoCA」や「../../CA」などになっていると思います。
キーペアの生成
まず、下記のコマンドを実行し、キーペアを生成します。
$ openssl genrsa -rand /dev/random 2048
証明書に使用するキーの長さは、本稿執筆の時点では2048ビット以上にするのがよいと言われています。なので、ここでは「2048」を指定しています。使用するランダムデバイスは/dev/urandomではなく、「/dev/random」を指定し、よりランダムな乱数が生成されることを期待しています。
/dev/randomを使用するにはエントロピーをたくさん貯める必要があります。エントロピーを速く貯めるには、コンソールでキーボードやマウスを動かしまくるといったことが行われますが、別の端末を立ち上げて下記のコマンドを実行するのが手っ取り早いです。
$ find / -type foobar >/dev/null 2>&1; ls -R / >/dev/null 2>&1; sync
この方法であれば手が疲れることもないし、リモート接続であっても速くエントロピーを貯めることができます。
ちなみに、エントロピーの貯まり具合は下記で確認できます。どんなコマンドを実行すると速く貯まるか調べてみるとよいでしょう。
$ cat /proc/sys/kernel/random/entropy_avail
証明書署名要求の作成
キーペアを生成したら、次は証明書署名要求 (Certificate Signed Request, CSR) を作成します。
$ openssl req -new -key private/cakey.pem -config openssl.cnf -out careq.pem
下記のように-x509 オプションを指定すれば、いきなりオレオレ認証局の証明書を作成することができますが、この方法だと細かい設定ができないので、今回はやりません。
$ openssl req -new -x509 -key private/cakey.pem -config openssl.cnf -out cacert.pem
証明書署名要求に自己署名
証明書署名要求に自己署名する前に、発行した証明書の履歴を格納する index.txt ファイルと、次に発行する証明書のシリアル番号を格納する serial ファイルを作成しておきます。これらのファイルを正しく作成しておかないと、証明書に署名しようとした時にエラーが発生します。
$ touch index.txt $ echo 00 > serial
次に、X509v3拡張属性を設定するためのファイルを作成します。下記の3つを指定すればよいでしょう。
$ cat <<EOF > v3_ca basicConstraints = critical, CA:true keyUsage = critical, cRLSign, keyCertSign subjectKeyIdentifier=hash EOF
basicConstraintsの「CA:true」は認証局の証明書であることを設定しています。「CA:true」を指定する場合はcritialフラグを設定する必要があります。keyUsageはキーペアの用途を制限します。認証局の証明書なので、「cRLSign」と「keyCertSign」を設定しています。それぞれ、CRLへの署名と証明書への署名です。最後にsubjectKeyIdentifierを設定しています。「hash」は公開鍵のハッシュ値を埋め込むことを意味します。このハッシュ値と同じ値をこの認証局が発行した証明書のauthorityKeyIdentifierに埋め込むことで、その証明書がこの認証局から発行されたものであることを素早く確認できます。
続いて、証明書署名要求に自己署名します。期間は2015-03-01から2025-03-31までの10年間を指定しています。最後の「Z」を忘れると不正な証明書とみなされる場合があるので注意してください。
$ openssl ca -in careq.pem -selfsign -notext -config openssl.cnf -outdir . \ -extfile v3_ca -out cacert.pem -startdate 150301000000Z -enddate 250331235959Z
内容を確認し、間違いがなければ「Y+Enter」を2回押してください。これで、オレオレ認証局が完成します。
サーバ証明書の発行
続いて、構築したオレオレ認証局を用いて、サーバ証明書を発行してみましょう。
キーペアの生成
これはオレオレ認証局を構築した時と同じです。キーの長さは2048ビット、ランダムデバイスは「/dev/random」を指定しています。
$ openssl genrsa -rand /dev/random 2048
証明書署名要求の作成
キーペアを生成したら、次は証明書署名要求 (Certificate Signed Request, CSR) を作成します。これもオレオレ認証局を構築した時と同じです。
$ openssl req -new -key private/server.csr -config openssl.cnf -out server.csr
証明書署名要求に署名
次に、X509v3 拡張属性を設定するためのファイルを作成します。下記の4つを指定すればよいでしょう。
$ cat <<EOF > v3_server basicConstraints = CA:false keyUsage = critical, digitalSignature, keyEncipherment extendedKeyUsage = serverAuth authorityKeyIdentifier=keyid,issuer EOF
basicConstraintsの「CA:false」は認証局の証明書ではないことを設定しています。この証明書を使用して証明書を発行できないようにしています。keyUsageはキーペアの用途を制限します。サーバ証明書なので、「digitalSignature」と「 keyEncipherment」を指定しています。それぞれ、デジタル署名とキーの暗号化を指定しています。extendedKeyUsageは拡張キー使用法と呼ばれるもので、「サーバ認証」を指定しています。もし、クライアント用の証明書の場合は「クライアント認証」を指定します。authorityKeyIdentifierはkeyidとissuerを指定しています。これは、認証局の証明書にsubjectKeyIdentifierが含まれている場合はその値(認証局の公開鍵のハッシュ)を、含まれていない場合は認証局の証明書のDistinguishedNameを設定することを意味します。ここでは、認証局を構築するときにsubjectKeyIdentifierを指定しているので、その値が設定されます。
続いて、証明書署名要求に署名します。期間は2015-03-01から2017-03-31までの2年間を指定しています。最後の「Z」を忘れると不正な証明書とみなされる場合があるので注意してください。
$ openssl ca -in server.csr -notext -config openssl.cnf -outdir . \ -extfile v3_server -out server.crt -startdate 150301000000Z -enddate 170331235959Z