Oracle Linux 6でCAを作ってみた。RHEL6やCentOS6でも通用するはず。

CAでいろいろ探してみたがCA.shとかわけわからんもんを使うという話が出てきて、OL6にCA.shがどこにあるのかそもそもあるのか分からなかったっつーか/etc/pki/tls/miscにCAというスクリプトがあるが中を見てもいまいちよく分からなかったのでopensslコマンド直打ちで作る事にした。以下、途中のコマンドを打つところは、CAが行うコマンドを「#」、普通はCAじゃない人が行うコマンドを「$」としている。
OL6では/etc/pki/CAというところにCAを置くようなopenssl.cnfになっていたのでそのままそこを使う。ここは755になっているので念のために

# chmod 700 /etc/pki/CA

でroot以外触れなくする。(本来は/etc/pki/CA/privateというのがrootクローズドならしい)

まず、/etc/pki/tls/openssl.cnfのcountryName_defaultとかを適切に設定する。今回は以下の内容を変えた。

# vi /etc/pki/tls/openssl.conf
[req_distinguished_name]
countryName_default=JP
stateOrProvinceName_default=Hiroshima
localityName_default=Hiroshima
0.organizationName_default=UN-SOFT Corp., Inc.
[usr_cert]
nsCertType=server
nsComment=
[v3_ca]
keyUsage=cRLSign, KeyCertSign
nsCertType=sslCA, emailCA
[client_cert] ←セクションごと追加する
nsCertType=client

おっとまずい、これではこのエントリを見に来た人に私が広島市に住んでいる事がばれてしまうではないか。ここを読んだ人は読み終わった後に忘れていただきたい。ちなみに私はUN-SOFTを法人(株式会社)化していないので上の組織名を公的に使うと警察だか誰かに怒られる(多分)。他にもCo. Ltd.とかはオレオレ証明書としては別にいいけどその証明書を誰でも見れるWebサーバに仕込むのはダメである(多分)。Co. Ltd.というのはえげれすかどこかで会社(Company)であり有限責任会社(Limited Company)であると公的に宣言したという意味になるだか何か聞いた事がある。テストで作る場合は万が一他の人に見られてもいいようにUN-SOFT Private Organizationとか名乗る方が良いだろう。
次にCA管理に必要なファイルを作る。index.txtとserial。

# cd /etc/pki/CA
# touch index.txt
# echo 00 > serial

ではCA用の秘密鍵を作りましょう。

# openssl genrsa -out ca.key 2048

そして秘密鍵の署名要求を作る。

# openssl req -new -key ca.key -out ca.csr

いろいろ質問されるのでJPとかHiroshimaとか適当に答える。国とか県とかは先ほどopenssl.cnfに設定したのが出てくるので基本的にはそれをそのまま使えば良い。重要なのはCommon Nameくらい。ここでは「Anmochi CA」とした。これで署名要求CSRファイルが作成される。
ではこれを自己署名してみよう。有効期間はどどんと100年だ。やっぱりCA、100年経っても大・丈・夫。

# openssl ca -in ca.csr -out ca.crt -keyfile ca.key -selfsign -days 36500 -extensions v3_ca

-extensions v3_caというコマンドラインオプションを忘れないように注意。これを忘れると別の署名がつけられる。ところで、openssl.cnfのv3_caセクションを見るとわかるが、何に対して署名するのかは署名要求ではなくCAの署名時に決定する。署名をリクエストする側は何に対して署名されているのか戻ってくるまでのお楽しみという訳だな。

ついでにWebサーバのサーバ証明書を今のオレオレCA証明書で作ってみよう。こちらはコマンドオプションが少し変わるくらいで基本的には同じ処理(秘密鍵を作り、署名要求を作り、署名する)だ。面倒なので同じ場所でやる。読者諸兄は別の場所でやってください。

$ openssl genrsa -out server.key 2048
$ openssl req -new -key server.key -out server.csr

質問の答えはCommon NameにWebサーバのFQDNを入れる以外はCAの時と同じ。

# openssl ca -in server.csr -out server.crt -keyfile ca.key -cert ca.crt -days 3650

selfsignじゃなくてca.crtを使うのと、-extensionsオプションが無くなっているのに気を付けていただきたい。

このCAをどこかの社内全体で使うならクライアント証明書の作り方もやっておこう。

$ openssl genrsa -out client.key 2048
$ openssl req -new -key client.key -out client.csr

質問の答えはCommon Nameに個人名とかアカウント名を入れる以外はCAの時と同じ。

# openssl ca -in client.csr -out client.crt -keyfile ca.key -cert ca.crt -days 365 -extensions client_cert

署名時のextensionsにclient_certと指定されている。これが冒頭でopenssl.cnfに追記したclient_certセクションを指し示し、nsCertTypeがclientである署名になる。
さて、これを使うにはpkcs #12という形式にするのが吉らしいので作る。

$ openssl pkcs12 -export -certfile ca.crt -in client.crt -inkey client.key -out client.p12

client.key(秘密鍵)を含むファイルになるのでその部分を読もうとした時に使うパスワードを決めて2度入力する。これは普通署名者ではなくクライアント本人にやってもらう事になる。これでInteret ExplorerやFirefoxやThunderbirdでクライアント証明書として使う事ができるようになった。
ところで、短期に雇う人用とかクライアント証明書の場合は厳密に有効期間を決めたいときがある(もちろんサーバ証明書でも)。-daysオプションだと現在日時からの有効期間となるので、0時0分0秒開始がいいとか、開始日も指定したいという場合は次のようにすれば良い。2013年1月1日0時0分0秒から2014年1月1日0時0分0秒の間有効な証明書にしたければ

# openssl ca -in client.csr -out client.crt -keyfile ca.key -cert ca.crt -startdate 20130101000000Z -enddate 20140101000000Z -extensions client_cert

とする。-startdateと-daysの組み合わせでは開始日時はうまくいくが、終了日時が開始日時起算ではなく現在日時からになるようだ。また、ここで指定する日時はGMTなのでこの証明書は日本では2013年1月1日9時0分0秒から2014年1月1日9時0分0秒まで有効になる。もちろん-enddateだけを指定する事もできる。

と、ここまでやってみたが証明書をWindowsにインポートしてみると「この証明書の目的」が、CA証明書は全ての発行ポリシー、すべてのアプリケーションポリシーの2つになっていて、サーバ証明書はすべてのアプリケーションポリシーの1つになっている。Windows 7に入っている他のCA証明書はここの結構いろいろ書かれてるわね。こういうのはどうやれば良いのかしら。