どぅーちゅいむーにー

これ、Twitterでよくね?という日々の記録かも

独自認証局の構築とクライアント認証 CentOS 5.3 + OpenSSL + Apache

かなり久しぶりの記事になったなぁ・・・

備忘録。
SSL 環境でクライアント認証を行うシステムで、クライアント証明書をUSBトークンに格納して・・・という要件の調査にあたって構築した環境のメモ。
ちょいと古めの環境ですが。


# uname -a
Linux hogehoge.server.jp 2.6.18-164.el5 #1 SMP Thu Sep 3 03:33:56 EDT 2009 i686 i686 i386 GNU/Linux
# cat /etc/redhat-release
CentOS release 5.3 (Final)
環境情報?

CA の場所:/etc/pki/CA
作業場所?:/etc/pki/tls/misc
まずは CA の構築。
openssl.conf の修正箇所とか。この環境、何度か使っているので何を修正したかよくわからなくなってきていますが、とりあえず今回修正した箇所。

dir = /etc/pki/CA # 相対パスだとよくわからなくなるんですよね・・・
・・・
policy = policy_match

# For the CA policy
[ policy_match ]
・・・
organizationName = supplied # テスト環境なので match でも良いのですが。
・・・
[ req_distinguished_name ]
・・・
countryName_default = JP # いいかげん毎回入力するに疲れた
・・・
stateOrProvinceName_default = Tokyo # いいかげん毎回入力するに疲れた
・・・
localityName_default = Bunkyo # いいかげん毎回入力するに疲れた
・・・
0.organizationName_default = xxx # いいかげん毎回入力するに疲れた
・・・
basicConstraints=CA:TRUE # CA構築時だけ。あとで FALSE に変更します(たぶん)
・・・
nsCertType = sslCA, emailCA # コメントアウト外し

いざ、CA構築。
/etc/pki/CA に古いバージョンの CA があったので、mv で退避。
以下、会社名と Common Name は実際に入力した値から適当に変更しています。

# pwd
/etc/pki/tls/misc
# ./CA -newca
CA certificate filename (or enter to create)

Making CA certificate ...
Generating a 1024 bit RSA private key
.............++++++
...++++++
writing new private key to '../../CA/private/./cakey.pem'
Enter PEM pass phrase:
Verifying - Enter PEM pass phrase:

        • -

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) [JP]:
State or Province Name (full name) [Tokyo]:
Locality Name (eg, city) [Bunkyo]:
Organization Name (eg, company) [Secret Corporation]:
Organizational Unit Name (eg, section) :SI
Common Name (eg, your name or your server's hostname)
:ca.kakinohana.biz
Email Address :

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password :
An optional company name []:
Using configuration from /etc/pki/tls/openssl.cnf
Enter pass phrase for ../../CA/private/./cakey.pem:
Check that the request matches the signature
Signature ok
Certificate Details:
Serial Number: 0 (0x0)
Validity
Not Before: Apr 25 02:17:59 2011 GMT
Not After : Apr 24 02:17:59 2014 GMT
Subject:
countryName = JP
stateOrProvinceName = Tokyo
organizationName = Secret Corporation
organizationalUnitName = SI
commonName = ca.kakinohana.biz
X509v3 extensions:
X509v3 Basic Constraints:
CA:TRUE
Netscape Cert Type:
SSL Server
Netscape Comment:
OpenSSL Generated Certificate
X509v3 Subject Key Identifier:
4C:44:5F:D5:BE:0E:2E:1B:47:7B:78:4D:7D:7E:6D:A4:F6:48:10:0E
X509v3 Authority Key Identifier:
keyid:4C:44:5F:D5:BE:0E:2E:1B:47:7B:78:4D:7D:7E:6D:A4:F6:48:10:0E

Certificate is to be certified until Apr 24 02:17:59 2014 GMT (1095 days)

Write out database with 1 new entries
Data Base Updated
#

つぎ、サーバ証明書
openssl.cnf の変更箇所。

#basicConstraints=CA:TRUE
basicConstraints=CA:FALSE # TRUE から FALSE に
・・・
#nsCertType = sslCA, emailCA
nsCertType = server # sslCA から server に。
キーペア、CSR、署名と続く。

# ./CA -newreq
Generating a 1024 bit RSA private key
.......++++++
..................++++++
writing new private key to 'newkey.pem'
Enter PEM pass phrase:
Verifying - Enter PEM pass phrase:

        • -

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) [JP]:
State or Province Name (full name) [Tokyo]:
Locality Name (eg, city) [Bunkyo]:
Organization Name (eg, company) [Secret Corporation]:
Organizational Unit Name (eg, section) :
Common Name (eg, your name or your server's hostname)
:test.kakinohana.biz
Email Address :

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password :
An optional company name []:
Request is in newreq.pem, private key is in newkey.pem
# ls -ltr
合計 56
・・・
-rw-r--r-- 1 root root 688 4月 25 11:29 newreq.pem
-rw-r--r-- 1 root root 963 4月 25 11:29 newkey.pem
# ./CA -sign
Using configuration from /etc/pki/tls/openssl.cnf
Enter pass phrase for /etc/pki/CA/private/cakey.pem: ※パスフレーズ入力
Check that the request matches the signature
Signature ok
Certificate Details:
Serial Number: 1 (0x1)
Validity
Not Before: Apr 25 02:31:24 2011 GMT
Not After : Apr 24 02:31:24 2012 GMT
Subject:
・・・
X509v3 extensions:
・・・

Certificate is to be certified until Apr 24 02:31:24 2012 GMT (365 days)
Sign the certificate? [y/n]:y ← y と入力


1 out of 1 certificate requests certified, commit? [y/n]y ← y と入力
Write out database with 1 new entries
Data Base Updated
Certificate:
Data:
・・・
-----BEGIN CERTIFICATE-----
・・・
-----END CERTIFICATE-----
Signed certificate is in newcert.pem
# ls -ltr
合計 56
・・・
-rw-r--r-- 1 root root 688 4月 25 11:29 newreq.pem
-rw-r--r-- 1 root root 963 4月 25 11:29 newkey.pem
-rw-r--r-- 1 root root 3287 4月 25 11:31 newcert.pem

そんなわけで、作成完了。
作成したサーバ関連のファイルはリネームして退避。

# openssl rsa -in ./server.key -out server_no_p.key
# ls -ltr
合計 56
-rw-r--r-- 1 root root 688 4月 25 11:29 server_csr.pem # newreq.pem
-rw-r--r-- 1 root root 963 4月 25 11:29 server.key # newkey.pem
-rw-r--r-- 1 root root 3287 4月 25 11:31 server_cert.pem # newcert.pem
-rw-r--r-- 1 root root 887 4月 25 11:37 server_no_p.key # newkey.pem からパスフレーズ除去
というわけで、クライアント証明書の作成。
の前に openssl.cnf を修正

#nsCertType = server
・・・
nsCertType = client, email # 次はクライアント。なお、CA:FALSE のままです。
いざ。

# ./CA -newreq
Generating a 1024 bit RSA private key
.....................++++++
...........................................++++++
writing new private key to 'newkey.pem'
Enter PEM pass phrase:
Verifying - Enter PEM pass phrase:
-----
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) [JP]:
State or Province Name (full name) [Tokyo]:
Locality Name (eg, city) [Bunkyo]:
Organization Name (eg, company) [Secret Corporation]:
Organizational Unit Name (eg, section) []:
Common Name (eg, your name or your server's hostname) []:issei.kakinohana.biz (こんなサーバいませんのであしからず)
Email Address []:

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
Request is in newreq.pem, private key is in newkey.pem
# ls -ltr
・・・
-rw-r--r-- 1 root root 887 4月 25 11:37 server_no_p.key
-rw-r--r-- 1 root root 668 4月 25 11:41 newreq.pem
-rw-r--r-- 1 root root 963 4月 25 11:41 newkey.pem

newreq.pem、newkey.pem ができました。
署名。

# ./CA -sign
Using configuration from /etc/pki/tls/openssl.cnf
Enter pass phrase for /etc/pki/CA/private/cakey.pem:
Check that the request matches the signature
Signature ok
Certificate Details:
Serial Number: 2 (0x2)
Validity
Not Before: Apr 25 02:43:34 2011 GMT
Not After : Apr 24 02:43:34 2012 GMT
Subject:
・・・
X509v3 extensions:
X509v3 Basic Constraints:
CA:FALSE
Netscape Cert Type:
SSL Client, S/MIME
・・・

Certificate is to be certified until Apr 24 02:43:34 2012 GMT (365 days)
Sign the certificate? [y/n]:y ← y と入力


1 out of 1 certificate requests certified, commit? [y/n]y ← y と入力
Write out database with 1 new entries
Data Base Updated
Certificate:
Data:
・・・

-----BEGIN CERTIFICATE-----
・・・
-----END CERTIFICATE-----
Signed certificate is in newcert.pem
# ls -ltr
・・・
-rw-r--r-- 1 root root 3268 4月 25 11:43 newcert.pem

newcert.pem ができましたとさ。
んで、p12 形式に。

# openssl pkcs12 -export -in newcert.pem -inkey newkey.pem -certfile ../../CA/cacert.pem -out newcert.p12
Enter pass phrase for newkey.pem: ※パスフレーズ
Enter Export Password: ※エクスポート用パスワード
Verifying - Enter Export Password: ※確認
# ls -ltr
合計 72
・・・
-rw-r--r-- 1 root root 668 4月 25 11:41 newreq.pem
-rw-r--r-- 1 root root 963 4月 25 11:41 newkey.pem
-rw-r--r-- 1 root root 3268 4月 25 11:43 newcert.pem
-rw-r--r-- 1 root root 2533 4月 25 11:46 newcert.p12
このあたり↑がクライアントの証明書。


というわけで、確認。

# pwd
/etc/pki/tls/misc
# ls -ltr
合計 72
・・・
-rw-r--r-- 1 root root 688 4月 25 11:29 server_csr.pem
-rw-r--r-- 1 root root 963 4月 25 11:29 server.key
-rw-r--r-- 1 root root 3287 4月 25 11:31 server_cert.pem ※ サーバ証明書
-rw-r--r-- 1 root root 887 4月 25 11:37 server_no_p.key ※ サーバの秘密鍵(パスフレーズなし)
-rw-r--r-- 1 root root 668 4月 25 11:41 newreq.pem
-rw-r--r-- 1 root root 963 4月 25 11:41 newkey.pem
-rw-r--r-- 1 root root 3268 4月 25 11:43 newcert.pem
-rw-r--r-- 1 root root 2533 4月 25 11:46 newcert.p12 ※クライアント証明書
実際に使うのは※をつけた3つかな。server_no_p.key と server_cert.pem を /etc/pki/ssl/0425/ にコピー。

# pwd
/etc/pki/ssl/0425
# ls -ltr
合計 8
-rw-r--r-- 1 root root 887 4月 25 11:51 server_no_p.key
-rw-r--r-- 1 root root 3287 4月 25 11:51 server_cert.pem
Apache の設定。今回は、CentOS にデフォルトでインストールされているものではなく、別途インストールした Apache への設定。
インストールディレクトリは /opt/apache となっています。

・・・
SSLCertificateFile "/etc/pki/ssl/0425/server/server_cert.pem"
・・・
SSLCertificateKeyFile "/etc/pki/ssl/0425/server/server_no_p.key"
・・・
SSLCertificateChainFile "/etc/pki/CA/cacert.pem" # CA の証明書をここに指定。
・・・
SSLCACertificatePath "/etc/pki/CA"
SSLCACertificateFile "/etc/pki/CA/cacert.pem"
・・・
SSLVerifyClient require # クライアント認証を。
SSLVerifyDepth 1
以上で設定は終わり。
あとは作成した newcert.p12 を使ってアクセスする感じ。
結果としては、ブラウザにクライアント証明書を設定して確認したところ、IE6 & Firefox3.6.16 on Windows XP SP3 ではOK。
しかしながら、某USBトークンに設定したところ Windows XP SP3 上では IE6 & Firefox とも認識されず。
でも、Windows 7 + IE8 だと OK でした。


なお、Firefox については、以前上記とはちょっと異なる手順(CA:TRUEあたりが違う)で作成したときにはうまくいきました。
そのときは IE6 でダメだったので、今回 IE でうまくいくようにと再チャレンジしたのですが、今度は Firefox でうまくいかなかったというオチ。
ちなみに、ブラウザがUSB トークンに格納された証明書を認識してくれるためには、IEの場合は Microsoft Base Smart Card Cryptographic Service Provider (exe ファイル的には Windows-KB909520-v1.000-x86-JPN.exe)をインストール、Firefox については .NET PKCS#11 のライブラリ(http://www.gemalto.com/products/dotnet_card/resources/libraries.html)をインストールし、セキュリティデバイスの設定を行いました。


なかなか難しい・・・