証明書は認証局 (CA) が公開鍵 (をもとに情報を付加した証明書署名要求 (CSR; certificate signing request)) に署名をしたものです。一般的に証明書は公開鍵を内包しています。
上記ページで概念的に紹介した、サーバ証明書およびクライアント証明書を実際にコマンド例を示しつつ発行します。
証明書は認証局 (CA) が 証明書署名要求 (CSR; certificate signing request) に署名をしたものです。認証局 (CA) は秘密鍵を持っています。署名にはその秘密鍵を使用します。つまり、署名に必要なものは秘密鍵だけです。認証局の秘密鍵以外の適当な秘密鍵で署名すると形式的には証明書が完成します。しかしながらその適当な秘密鍵の保持者は証明書の信頼性を第三者に一般に保証することができないためオレオレ証明書などと称されます。
認証局は自分で構築することができます。これを俗にオレオレ認証局と称します。
クライアント証明書の運用を考える場合は必ず認証局が必要です。ここではベリサインなどの認証局は使用せず、独自にオレオレ認証局を構築します。オレオレクライアント証明書の運用を考えているということになります。オレオレサーバ証明書の運用のみを考える場合は以降の手順は不要です。
root で作業します。なお、作業環境は CentOS 6.6 です。
$ sudo su -l
PKI ディレクトリに移動します。
$ cd /etc/pki/
独自認証局を構築するためのディレクトリが用意されています。中身は空です。
$ ls /etc/pki/CA/
certs crl newcerts private
必要なファイルをコピーしてきます。
$ cp tls/misc/CA CA/
$ cp tls/openssl.cnf CA/
内容を編集します。
$SSLEAY_CONFIG
が最初に登場する前に一行 SSLEAY_CONFIG="-config /etc/pki/CA/openssl.cnf"
追加DAYS
および CADAYS
の既定値をそれぞれ 100 年 (36500 日) に変更して事実上無期限にするREQ
を REQ="$OPENSSL req $SSLEAY_CONFIG -sha256"
に変更 (sha256 を既定値にする)CA
を CA="$OPENSSL ca $SSLEAY_CONFIG -md sha256"
に変更 (sha256 を既定値にする)req_distinguished_name
セクションの既定値を変更 countryName_default
, stateOrProvinceName_default
, localityName_default
, 0.organizationName_default
認証局用の秘密鍵を生成して、更にその秘密鍵をもとに作成した公開鍵と国情報などを合わせた CSR を生成します。更に自分の秘密鍵で署名します。/etc/pki/CA/CA
には CATOP=/etc/pki/CA
という一行があります。ルート CA は自分で自分の CSR に署名します。これらの処理はコマンド一つで実行できるようになっています。
$ cd /etc/pki/CA
$ ./CA -newca (最初はそのままエンターです)
作成中に求められるコモンネームは認証局の識別子です。ここでは "MyCA" としました。また、認証局の秘密鍵のパスワードは my_ca_pass
としました。認証局用の CSR を生成するときに認証局秘密鍵のパスワードが早速必要になります。
将来的に証明書を無効にする場合に備えて破棄リストを生成しておきます。
$ cd /etc/pki/CA
$ echo 00 > crlnumber
$ openssl ca -config openssl.cnf -gencrl -out crl.pem
以上で CA が構築されました。
こちらのページなどを参考にします。一般的にオレオレ証明書の作成といった場合は CA を構築せずに以下のようなコマンドで発行する場合が多いようです。
秘密鍵の作成
$ openssl genrsa -out my-private-key.pem 2048
CSR の作成 (コモンネームなどの情報を入力)
$ openssl req -sha256 -new -key my-private-key.pem -out csr.pem
認証局 CA がないため自分の秘密鍵を流用して署名 (100 年の有効期間)
$ openssl x509 -sha256 -req -days 36500 -in csr.pem -signkey my-private-key.pem -out my-certificate.crt
秘密鍵
$ openssl rsa -text -in my-private-key.pem
Private-Key: (2048 bit)
...
CSR
$ openssl req -text -in csr.pem
証明書
$ openssl x509 -text -in my-certificate.crt
「CA を構築していない場合」の手順または以下のバッチコマンドで秘密鍵と CSR を準備します。
$ sudo su -l
$ cd /etc/pki/CA
$ ./CA -newreq
パスフレーズは my_server_pass
としました。CN は localhost
としました。成果物は newreq.pem
および newkey.pem
です。次に構築した CA で署名します。
$ sudo su -l
$ cd /etc/pki/CA
$ ./CA -sign
成果物 newcert.pem
が生成されました。同じ内容のファイルが newcerts/DB04B363DA63FFA4.pem
(ファイル名はシリアル番号で環境依存) にも生成されています。シリアル連番 serial や発行証明書のリスト index.txt も更新されました。カレントディレクトリに生成されたままのファイルを移動させて整理します。newcerts のシリアル番号とファイル名を同じにしておきます。
$ mkdir csr
$ mv newreq.pem csr/DB04B363DA63FFA4.pem
$ mv newkey.pem private/DB04B363DA63FFA4.pem
内容としては同じではありますが、使い勝手をよくするために秘密鍵からパスワードを解除して証明書からは余分な文字列を除去して依頼主に渡します。
$ cd /etc/pki/CA
$ mkdir share
$ openssl rsa -in private/DB04B363DA63FFA4.pem -out share/localhost.key
$ mv newcert.pem share/localhost.crt
$ openssl x509 -in share/localhost.crt -out share/localhost.crt
証明書から削除した余分な文字列は上述の通りコマンドで再確認できます。
$ openssl x509 -text -in share/localhost.crt
必要なソフトウェアをインストールします。
$ sudo yum install httpd mod_ssl
用意したサーバ証明書を設定します。
$ sudo vi /etc/httpd/conf.d/ssl.conf
SSLCertificateFile /etc/pki/CA/share/localhost.crt
SSLCertificateKeyFile /etc/pki/CA/share/localhost.key
サービスを起動します。
$ sudo service httpd start
アクセスしてみましょう。
$ curl https://localhost/ ←オレオレサーバ証明書のためエラー
$ curl https://localhost/ -k ←証明書を強制的に信頼するオプション
$ curl https://localhost/ --cacert /etc/pki/CA/cacert.pem ←指定した認証局証明書を信頼するオプション
上記 curl コマンドの二つ目はブラウザで信頼性のないサーバ証明書を個別に信頼する処理に相当します。三つめは構築した CA の証明書をブラウザにインポートすることに相当します。Firefox の場合は以下のようになります。
Firefox → オプション → 詳細 → 証明書 → 証明書を表示 → 認証局証明書 → インポート → cacert.pem → すべてチェックして OK
証明書をインポートした CA で署名された証明書であればブラウザは信頼のある証明書として扱うようになります。ただし、コモンネーム (CN) が一致しない場合はやはりブラウザに信頼されないことに注意してください。他人のサイトの証明書を勝手に利用したなりすまし防止のためです。
必要なソフトウェアをインストールします。
$ sudo yum install epel-release (環境によっては不要)
$ sudo yum install nginx
用意したサーバ証明書を設定します。コメントアウトをすべて解除して以下のように編集します。
$ sudo vi /etc/nginx/conf.d/ssl.conf
ssl_certificate /etc/pki/CA/share/localhost.crt;
ssl_certificate_key /etc/pki/CA/share/localhost.key;
サービスを起動します。
$ sudo service nginx start
アクセスしてみましょう。
$ curl https://localhost/ ←オレオレサーバ証明書のためエラー
$ curl https://localhost/ -k ←証明書を強制的に信頼するオプション
$ curl https://localhost/ --cacert /etc/pki/CA/cacert.pem ←指定した認証局証明書を信頼するオプション
Apache や nginx は HTTP で動作させて ELB にサーバ証明書をアップロードすることができます。クライアントは HTTPS 通信を ELB に対して行います。詳細は『SSL 通信に対応した ELB』に記載しました。