以前書いた「FujiSSLでSANs対応のドメイン認証をとる」のリライトです。
当時はFujiSSLでSANs対応のドメイン認証取得をするために相応のCSRを作る必要があったので、opensslコマンドを使ってCSRを作る内容をまとめたのでした。(現在はwwwサブドメインありなしを自動的に対応してくれる模様)
その後、GoGetSSLで認証取得する際にも似たような内容を書いてしまったので、これらを統合して情報をアップデートします。
CSRとは
公開鍵証明書を発行してもらう際に認証局に提出するファイルです。Certificate Signing Request(証明書署名要求)の頭文字でCSR。
中身は申請者の識別情報と署名をしてもらう公開鍵です。
申請者の識別情報はコモンネーム(暗号化通信をおこなうサイトのurl)やサイト運営者の情報など、opensslでCSRを生成する際に入力する内容になります。
opensslコマンドで秘密鍵を作る
というわけで公開鍵ペアを作るわけですが、公開鍵の暗号方式にあるようにssh-keygenで鍵ペアを作ってしまうと申請者の識別情報が入ったCSRが生成されません。
なのでまずはopensslコマンドで秘密鍵だけを作ります。
opensslにはいくつかのサブコマンドがありますが、RSA暗号を利用した公開鍵用の秘密鍵(ややこしいな!)を作るサブコマンドはgenrsa。
OpenSSL 1.1.1ではデフォルトで鍵のビット長が2048ビットになります。今ならこのビット長のままでよさそう。
-aes256オプションは秘密鍵を暗号化するためのアルゴリズム指定。秘密鍵が流出してしまうと色々と問題があるので、万が一のことを考えてこのパスフレーズを設定しておくのが無難です。
1 | # openssl genrsa -out www.example.com.key -aes256 |
公開鍵認証の暗号方式にあるとおり、ECDSAならもっと短いビット長で安全な暗号強度を確保できます。GoGetSSLではRSA暗号鍵だけでなく、ECDSA暗号鍵によるCSRも使えるようなので、こちらの生成方法も試してみます。
ECDSA暗号を利用した秘密鍵を扱うサブコマンドはecparam。秘密鍵を生成するには-genkeyパラメータが必要になります。またECDSAは何種類かの楕円曲線を指定できるので、ここでは一番無難なprime256v1を-nameオプションを使って指定しておきます。
1 | # openssl ecparam -name prime256v1 -genkey -out www.example.com.key |
ecparamサブコマンドでは秘密鍵の暗号化ができないので、一旦秘密鍵ファイルを作成したのちにecサブコマンドを使ってパスフレーズを設定します。
1 | # openssl ec -in www.example.com.key -out www.example.com.enc.key -aes256 |
opensslコマンドはフィルタとしても動作するので、-in/-outオプションで指定しているファイルの入出力先をパイプで繋げば、見かけ上パスフレーズなしの秘密鍵が生成されないのでよいかもしれません。タイプ数も減るね。
1 | # openssl ecparam -name prime256v1 -genkey | openssl ec -out www.example.com.enc.key -aes256 |
なお、秘密鍵にパスフレーズを設定すると、Webサーバーが秘密鍵を読み込む際にパスフレーズの入力が要求されてしまうので、サーバー設定をいじる必要があります。
Nginxの場合、ssl_certificate_key
ディレクティブの前にssl_password_file
ディレクティブを使ってパスフレーズファイルを指定します。パスフレーズは一行あたりひとつづつ書いておくと、秘密鍵読み込み時に順次トライしてくれます。
opensslコマンドでCSRを作る
CSRを扱うサブコマンドはreq。今回は新規作成なので-newオプションを指定します。
-keyで使用する秘密鍵を、-outで出力するCSRファイル名を指定します。いまどきの暗号強度はsha256で。RSA鍵もECDSA鍵も同じ操作になります。
1 | # openssl req -new -key www.example.com.key -out www.example.com.csr -sha256 |
前述のとおり入力した申請者情報と、秘密鍵から生成された公開鍵がCSRとして出力されます。
CSRはBase64で符号化されている(秘密鍵ファイルも同じだけど)ので、中身を見ても何が書いてあるかわかりません。これもreqサブコマンドを使うことで復号することができます。
1 | # openssl req -text -noout -in www.example.com.csr |
SANs対応のCSRを作るときは。。。
openssl.cnfを使って設定します。ファイルの在処はOSによってまちまちです。
- FreeBSD:/etc/ssl/openssl.cnf
- CentOS :/etc/pki/tls/openssl.cnf
オリジナルファイルのコピーを編集します。手順は以下のとおり。
- コメントアウトされているreq_extensions = v3_reqを有効化
- [ v3_req ]セクション内にsubjectAltName = @alt_namesを追記
- [ v3_req ]セクションの後に[ alt_names ]セクションを追加
1 | [ alt_names ] |
複数追加したいときはさらにDNS.2、DNS.3と続けます。
openssl.cnfが用意できたらopensslのサブコマンドreqに-configオプションで編集したopenssl.cnfファイルを指定します。
1 | # openssl req -config openssl.cnf -new -key www.example.com.key -out www.example.com.csr -sha256 |
本当にSANs対応のCSRになっているかどうかはreqサブコマンドの-textオプションで確認します。中ほどにSubject Alternative Nameの項目があり、wwwなしのドメインが指定されています。
1 | # openssl req -text -noout -in www.example.com.csr |
こんな感じですね。