証明書を取り扱う
SETUP
証明書
Web サイトの機密性を向上する上でよく利用される SSL を用いた通信ですが、その通信の信頼性をさらに保障するための仕組みとして、「証明書」 というものが存在します。
今回は OpenSSL の機能を利用して、Linux 上でこの証明書の発行や更新といった手続きを行うことに関するお話です。 なおこの文書は不確定な部分も含みますので参考程度に参照してください。
【認証局】 CA (認証局)を準備する
CA (認証局) を用意していない場合は、まずはそれを準備します。
ディレクトリとインデックスファイルの準備
ここではとりあえず、次のようなディレクトリ構成を想定しています。なお private/ ディレクトリは秘密鍵の格納に使う予定なので、パーミッションを 700 など、無用なユーザから参照できないようにしておくなどしておきます。
/etc/ca/
certs/
newcerts/
crl/
private/
そして CA が必要とするファイルを用意します。
cd /etc/ca
touch index.txt
echo 01 > serial
これで、証明書関連の情報が保存される予定の index.txt と、証明書を管理するシリアル番号を保存した serial というファイルが作成されます。
CA 基本設定の準備
また /etc/ca/ に、conf という名前のテキストファイルを用意します。これは認証局のディフォルト設定などを記述するもので、内容はたとえば次のような感じにします。
[ ca ]
default_ca =default_ca
x509_extensions =usr_cert
[ default_ca ]
dir =/etc/ca
certs =$dir/certs
crl_dir =$dir/crl
#CA_DB =
new_certs_dir =$dir/newcerts
certificate =$certs/ca.crt
serial =$dir/serial
crl =$crl_dir/ca.crl
private_key =$dir/private/ca.key
database =$dir/index.txt
#RANDFILE =
default_days =30
#default_startdate =
#default_enddate =
default_crl_days =30
#default_crl_hours =
default_md =md5
#preserve =no
policy =policy_match
x509_extensions =x509v3_extensions
#crl_extensions =
#msie_hack =
[ policy_match ]
countryName =optional
stateOrProvinceName =optional
organizationName =optional
organizationalUnitName =optional
commonName =supplied
emailAddress =optional
[ usr_cert ]
basicConstraints=CA:FALSE
nsCertType =sslCA,emailCA,server,client,email,objsign
#nsCertType =objsign
#nsCertType =client,email
#nsCertType =client,email,objsign
#nsComment ="OpenSSL Generated Certificate"
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid,issuer:always
[ x509v3_extensions ]
subjectKeyIdentifier=hash
basicConstraints =CA:true
nsCertType =sslCA,emailCA,server,client,email,objsign設定は大文字小文字などの区別がありますので、間違えないように気をつけましょう。間違えると、次の CRL ファイルの作成時や、署名依頼書から証明書を作成するときなどにエラーが発生します。
上記のうちのいくつかの項目についての補足です。
dir CA の基本となるディレクトリです。 certs crl_dir serial CA が次に発行する証明書に割り当てるシリアル番号が記録されたファイルです。 database CA が発行した証明書の情報が記録されるファイルです。 new_certs_dir CA が発行した証明書が保存されるディレクトリです。 certificate CA 自身の証明書ファイルです。 private_key CA 自身の秘密鍵ファイルです。
CA 自身の証明書等の準備
まずはこの CA 自身の秘密鍵を作成します。なお、以下の作業はすべて /etc/ca/ ディレクトリ上で行っているものとします。
/usr/bin/openssl genrsa -config conf -out private/ca.key -rand $A:$B:$C:$D 1024
ここで $A, $B, $C, $D というのは、なにかてきとうな大きさのファイルの名前で、ここに指定されたファイルデータからランダムせいを出すようです。既存のファイルであれば何を指定しても問題ないです。
続いて CA 自身の証明書を発行します。この CA をルート認証局 (最上位) とする場合と、別の CA の下位とする場合とで、証明書の作成方法が異なります。
自身の CA をルート認証局とする場合
次のようにして証明書を発行します。
/usr/bin/openssl req -config conf -new -x509 -days 90 -key private/ca.key -out certs/ca.crt
これで CA 自身の証明書が完成です。
別の CA の下位とする場合
この場合、次のように署名依頼書を作成します。
/usr/bin/openssl req -config conf -new -key private/ca.key -out ca.csr
そして出来上がった ca.csr ファイルを上位の CA に送って書名をしてもらいます。そして署名してもらった結果を ca.crt として /etc/ca/certs/ ディレクトリへ保存すれば準備完了です。
【共通項目】 入力項目の補足
ルート認証局にする場合もそうでない場合も、証明書または署名依頼書の作成の最中に次のような項目を訪ねられるので、入力します。
Country Name (2 letter code):
国名です。アルファベット2文字で指定するので、日本ならば JP となります。
State or Province Name (full name):
日本だと都道府県名にあたるようです。KANAGAWA といったように指定します。
Locality Name (eg, city):
日本だと市区町村名でしょうか。YOKOHAMA といったように指定すればよさそうです。
Organization Name (eg, company):
組織名です。
Organizational Unit Name (eg, section):
部署名などを指定するようです。
Common Name (eg, YOUR name):
認証局の名前でしょうか。インターネット・ホスト名や、電子メールアドレスなどを指定すればいいようです。
Email Address []:
認証局への連絡先アドレスでしょう。
【共通項目】 CRL ファイルの作成
CRL は証明書を無効にするときに使用するファイルだそうで、これも作成しておく必要があります。
/usr/bin/openssl ca -gencrl -config conf -out crl/ca.crl
【共通項目】 シンボリックリンクを作成する?
出来上がった証明書ファイルに対して、次のようにシンボリックリンクを張っておくといいとかどうとか…。
ln -s /etc/ca/certs/ca.crt certs/`openssl x509 -noout -hash < certs/ca.crt`.0
ln -s /etc/ca/crl/ca.crl crl/`openssl crl -noout -hash < crl/ca.crl`.r0
これはなにやらファイル名をハッシュ化することで検索を容易にするためのものだそうです。このようにハッシュ化しておいて、このファイル名を CA の設定ファイル (conf) へ記述するのが理想のようです。
【クライアント】 署名依頼書を発行する
これは CA 側の作業ではないですけど、クライアントが CA に対して証明書を発行してもらうためのファイルを準備する方法です。クライアント側でも OpenSSL を使用している場合は次のような感じとなります。
/usr/bin/openssl genrsa -out private/site1.key -rand $A:$B:$C:$D 1024
/usr/bin/openssl -req -new key private/site1.key -out site1.csr
ここで $A, $B, $C, $D というのは、なにかてきとうな大きさのファイルの名前で、ここに指定されたファイルデータからランダムせいを出すようです。既存のファイルであれば何を指定しても問題ないです。
また、署名依頼書の作成の最中に次のような項目を訪ねられるので、入力します。
Country Name (2 letter code):
国名です。アルファベット2文字で指定するので、日本ならば JP となります。
State or Province Name (full name):
日本だと都道府県名にあたるようです。KANAGAWA といったように指定します。
Locality Name (eg, city):
日本だと市区町村名でしょうか。YOKOHAMA といったように指定すればよさそうです。
Organization Name (eg, company):
組織名です。
Organizational Unit Name (eg, section):
部署名などを指定するようです。
Common Name (eg, YOUR name):
認証局の名前でしょうか。インターネット・ホスト名や、電子メールアドレスなどを指定すればいいようです。
Email Address []:
認証局への連絡先アドレスでしょう。
A challenge password []:
証明書を使用する際に必要なパスワードです。入力必須というわけではないようです。
An optional company name []:
組織名のオプションでしょうか…、とりあえず入力しなくてもいいようです。
これらを入力して、エラーがなければ、site1.csr という署名依頼書が出来上がります。これを認証局へ送って署名してもらうことで、証明書を手に入れることが出来ます。
【認証局】 証明書を発行する
クライアント側から提示された署名依頼書を使って、証明書を発行します。署名依頼書がたとえば /work/site1.csr として保存されているとして、/etc/ca/ ディレクトリにて次のような操作を行います。
/usr/bin/openssl ca -batch -config conf -out /work/site1.crt -infile /work/site1.csr
これにて証明書の発行は完了です。出来上がった site1.crt が証明書なので、これをクライアント側へ送り返します。
【認証局】 証明書を更新する
自身(ルート認証局)の証明書
証明書の有効期限が切れたりした場合、次のようにして証明書の更新を行います。手続きとしては、以前に使用した秘密鍵を使って新たに証明書ファイルを作成します。
とりあえず、現在の証明書の設定を確認したい場合は、次のようにします。
/usr/bin/openssl x509 -in ca.crt -noout -text
あとは最初に作成したときと同様に、次のようにして証明書を発行します。
/usr/bin/openssl req -config conf -new -x509 -days 90 -key private/ca.key -out certs/ca.crt
これで CA 自身の証明書が完成です。これを配れば更新完了となります。
自身に登録されている証明書
古い証明書を無効にした上で、あらたに新しい署名依頼書を受け取ってそれに署名をする、という流れになるようです。
無効にしたい証明書は、署名を行った際に certs ディレクトリに "シリアル番号.pem" という名前で保存されているので、index.txt から該当するシリアル番号を調べて crt (.pem) ファイルを特定することが可能です。
あとは次のようにして証明書を無効にすることが出来ます。
/usr/bin/openssl ca -config conf -revoke site1.crt
これでデータベースに、その証明書が失効したことを示すマークが付けられます。そして証明書を無効にしたら、改めて CRL ファイルを作成する必要があるとのことです。
/usr/bin/openssl ca -gencrl -config conf -out crl/ca.crl
あとは、新たに受け取った署名依頼書に署名をして、出来上がった証明書を送り届ければ更新完了、、、となるようです。
/usr/bin/openssl ca -batch -config conf -out /work/site1.crt -infile /work/site1.csr
ルート証明書を MacOS X の IE 5 へ組み込めるようにする
Windows 版の Internet Explorer の場合、「インターネットオプション」 の 「コンテンツ」 のところから、証明書の組み込みなどを行うことが出来るのですけど、Mac 版の方はそのような設定箇所がないようでした。
Web サイトに上記で作成した ca.crt を配置してダウンロードしてもテキストファイルとして受け取ってしまうし…。
調べてみたところ、どうやら DER 形式にてバイナリエンコードしたものをダウンロードさせてあげるといいようです。
なのでさっそく、ca.crt を DER エンコードした ca.der を作成してみます。
/usr/bin/openssl x509 -inform pem -outform der -in certs/ca.crt -out certs/ca.der
なお、今まで作成していた証明書は PEM 形式というもののようなので、混同を避けるならばいままでのも *.crt ではなくて *.pem としておくのもいいかもしれないですね。
さて、DER 形式の証明書が出来たらこれを Web サーバにて配布するのですけど、サーバの設定によっては *.der の MIME タイプを設定する必要があるようです。
Apache ならば、/usr/local/apache/conf/mime.types 内に次のような記述を追加して再起動してあげましょう。
application/x-x509-ca-cert der
これで *.der ファイルを転送する際に、その MIME タイプとして application/x-x509-ca-cert を付加してくれます。
これで設定完了です。
あとは MacOS X の IE 5.2 なりで上記の設定をした Web サーバから ca.der をダウンロードすれば、証明書の組み込みウィザード(?)が起動します。