ホーム > Web site / サイト作成

OpenSSLで作るCSR

以前書いた「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
2
3
4
5
6
7
# openssl genrsa -out www.example.com.key -aes256
Generating RSA private key, 2048 bit long modulus (2 primes)
...............+++++
..+++++
e is 65537 (0x010001)
Enter pass phrase for www.example.com.key:
Verifying - Enter pass phrase for www.example.com.key:

公開鍵認証の暗号方式にあるとおり、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
2
3
4
5
# openssl ec -in www.example.com.key -out www.example.com.enc.key -aes256
read EC key
writing EC key
Enter PEM pass phrase:
Verifying - Enter PEM pass phrase:

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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# openssl req -new -key www.example.com.key -out www.example.com.csr -sha256
Enter pass phrase for www.example.com.enc.key:
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) [AU]:JP
State or Province Name (full name) [Some-State]:Tokyo
Locality Name (eg, city) []:Nerima-ku
Organization Name (eg, company) [Internet Widgits Pty Ltd]:Example
Organizational Unit Name (eg, section) []:Example
Common Name (e.g. server FQDN or YOUR name) []:www.example.com
Email Address []:

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

前述のとおり入力した申請者情報と、秘密鍵から生成された公開鍵がCSRとして出力されます。

CSRはBase64で符号化されている(秘密鍵ファイルも同じだけど)ので、中身を見ても何が書いてあるかわかりません。これもreqサブコマンドを使うことで復号することができます。

1
2
3
4
5
6
7
8
9
10
11
12
# openssl req -text -noout -in www.example.com.csr
Certificate Request:
Data:
Version: 1 (0x0)
Subject: C = JP, ST = Tokyo, L = Nerima-ku, O = Example, OU = Example, CN = www.example.com
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
RSA Public-Key: (2048 bit)
Modulus:
00:ec:93:fb:80:66:47:40:bd:6a:aa:cc:fc:3e:81:
fc:ab:18:25:fc:89:93:ab:cb:df:b2:19:13:d9:51:
(以下略)

SANs対応のCSRを作るときは。。。

openssl.cnfを使って設定します。ファイルの在処はOSによってまちまちです。

  • FreeBSD:/etc/ssl/openssl.cnf
  • CentOS :/etc/pki/tls/openssl.cnf

オリジナルファイルのコピーを編集します。手順は以下のとおり。

  1. コメントアウトされているreq_extensions = v3_reqを有効化
  2. [ v3_req ]セクション内にsubjectAltName = @alt_namesを追記
  3. [ v3_req ]セクションの後に[ alt_names ]セクションを追加
1
2
[ alt_names ]
DNS.1 = example.com

複数追加したいときはさらにDNS.2、DNS.3と続けます。

openssl.cnfが用意できたらopensslのサブコマンドreqに-configオプションで編集したopenssl.cnfファイルを指定します。

1
2
3
4
5
# openssl req -config openssl.cnf -new -key www.example.com.key -out www.example.com.csr -sha256
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.
(以下略)

本当にSANs対応のCSRになっているかどうかはreqサブコマンドの-textオプションで確認します。中ほどにSubject Alternative Nameの項目があり、wwwなしのドメインが指定されています。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# openssl req -text -noout -in www.example.com.csr
Certificate Request:
Data:
Version: 1 (0x0)
Subject: C = JP, ST = Tokyo, L = Nerima-ku, O = Example, OU = Example, CN = www.example.com
(中略)
Requested Extensions:
X509v3 Basic Constraints:
CA:FALSE
X509v3 Key Usage:
Digital Signature, Non Repudiation, Key Encipherment
X509v3 Subject Alternative Name:
DNS:example.com
Signature Algorithm: sha256WithRSAEncryption
(以下略)

こんな感じですね。