2016/03/24(Thr)cygwinとOpenSSLを使ってオレオレ証明書を作る

はてブ数 2016/03/24 0:55 つーさ

CygwinとOpenSSLとでオレオレ証明書を作った記録。

この記事では、

root CAを作って、
server用証明書を発行し、
apache に server 証明書を取り込み、
クライアントには、ルート証明書を取り込み、
ブラウザでSSLの警告が出ずにSSL接続できるまで、を説明します。

とりあえず最新のOpenSSLを使ってるか確認しとこ。

$ openssl version
OpenSSL 1.0.2g  1 Mar 2016

うーん。
CygwinバンドルのOpenSSL使ったけど、
OpenSSL自体も自分でコンパイルした方がいいのかな、
という気もちょっとする?

ルートCAを作ってみる。

ホームに作業用ディレクトリを作ってその中でやってみる。

$ mkdir ssl && cd ssl

Cygwinにも、簡単にCA関連の作業が行えるCA.shがあるのでこれを利用してみる。
そのまま作ると、有効期限3年のCAができてしまうので、20年くらいに書き換えてみる。

いちおCA.shをコピーして書き換える。

$ cp /usr/ssl/misc/CA.sh .
$ vim ./CA.sh
 63: if [ -z "$DAYS" ] ; then DAYS="-days 365" ; fi  # 1 year
 64: CADAYS="-days 1095"     # 3 years
 65: REQ="$OPENSSL req $SSLEAY_CONFIG"

1095日ってかいてあるので、365*20 で、7200日に。

 64: CADAYS="-days 7200"     # 20 years

準備ができたら保存して、ルート証明書を作ってみる。

$ ./CA.sh -newca
CA certificate filename (or enter to create)
 ←Enterキーで新規作成。たぶん、中間認証局を作るときには上流のCAに署名してもらった証明書のファイル名を入れるのかな?
Making CA certificate ...
Generating a 2048 bit RSA private key
....+++
....+++
writing new private key to './demoCA/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) [AU]:JP ← 日本「JP」
State or Province Name (full name) [Some-State]:Nagano ←県名「Nagano」
Locality Name (eg, city) []:. ←市町村
Organization Name (eg, company) [Internet Widgits Pty Ltd]:tu3.jp ←団体名。
Organizational Unit Name (eg, section) []:. ←部署名。
Common Name (e.g. server FQDN or YOUR name) []:tu3.jp ← 認証局の名前。FQDNとか名前。
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 /usr/ssl/openssl.cnf
Enter pass phrase for ./demoCA/private/./cakey.pem: ←先ほど作成した秘密鍵のパスフレーズを入力
Check that the request matches the signature
Signature ok
Certificate Details:
        Serial Number: .... (0x...)
        Validity
            Not Before: Mar 21 16:22:15 2016 GMT
            Not After : Dec  7 16:22:15 2035 GMT
        Subject:
            countryName               = JP
            stateOrProvinceName       = Nagano
            organizationName          = tu3.jp
            commonName                = tu3.jp
        X509v3 extensions:
            X509v3 Subject Key Identifier: ..........................
            X509v3 Authority Key Identifier: ..........................

            X509v3 Basic Constraints:
                CA:TRUE
Certificate is to be certified until Dec  7 16:22:15 2035 GMT (7200 days)

Write out database with 1 new entries
Data Base Updated

demoCAというディレクトリができて、その中に証明書などは作られている。
demoCA/cacert.pem が、rootCAの証明書。 .cer などに拡張子を変更するとWindowsの証明書ビューアで開くこともできる。sha256で作れているっぽい。
demoCA/private/cakey.pem が秘密鍵。

中身はテキストのpem形式なのでバイナリのder形式に変換するには……。

$ openssl x509 -in demoCA/cacert.pem -outform der -out rootCA.der
$ cp rootCA.der rootCA.cer

.pem とか .der はフォーマットを表してて、.cer はWindowsの証明書拡張子。
.cerの中身はpemでもderでもいいみたい。

CRLの場所を含めるには?

http://d.hatena.ne.jp/akira_you/20050126/p1

$ vim /usr/ssl/openssl.cnf
224: [ v3_ca ]
 ...
261: # CRL distribution point
262: crlDistributionPoints = URI:http://tu3.jp/tu3.crl

別の証明書を作ってCAとして署名してみる。

ルートCAに提出するリクエストを作る。

$ ./CA.sh -newreq
Generating a 2048 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) [AU]:JP
State or Province Name (full name) [Some-State]:Hyogo
Locality Name (eg, city) []:Kobe
Organization Name (eg, company) [Internet Widgits Pty Ltd]:tu3.jp
Organizational Unit Name (eg, section) []:.
Common Name (e.g. server FQDN or YOUR name) []:tu3.jp ←サーバ証明書の場合はFQDN。
Email Address []:.

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:hogehoge
An optional company name []:
Request is in newreq.pem, private key is in newkey.pem

これで新しい秘密鍵と証明書発行のリクエストができる。
./newkey.pem 秘密鍵
./newreq.pem 証明書リクエスト

この証明書リクエストをCAにお願いして、CAで証明書を発行・署名してもらう流れ。

今回は自分がCAなので自分でリクエストを処理する。
./CA.shを使うと sign 時に$DAYSが書いてなくて openssl.cnf の設定値から変えられないので、自分で openssl コマンドを打つ。

155: -sign|-signreq)
156:     $CA -policy policy_anything -out newcert.pem -infiles newreq.pem
$  openssl ca -policy policy_anything -days 3650 -out newcert.pem -infiles newreq.pem
Using configuration from /usr/ssl/openssl.cnf
Enter pass phrase for ./demoCA/private/cakey.pem: ←ルートCAの秘密鍵
Check that the request matches the signature
Signature ok
Certificate Details:
        Serial Number: ........ (0x........)
        Validity
            Not Before: Mar 21 18:03:33 2016 GMT
            Not After : Mar 19 18:03:33 2026 GMT
        Subject:
            countryName               = JP
            stateOrProvinceName       = Hyogo
            localityName              = Kobe
            organizationName          = tu3.jp
            commonName                = tu3.jp
        X509v3 extensions:
            X509v3 Basic Constraints:
                CA:FALSE
            Netscape Comment:
                OpenSSL Generated Certificate
            X509v3 Subject Key Identifier:
                ....
            X509v3 Authority Key Identifier:
                keyid:....

Certificate is to be certified until Mar 19 18:03:33 2026 GMT (3650 days)
Sign the certificate? [y/n]:y ←署名するか?


1 out of 1 certificate requests certified, commit? [y/n]y ←コミット

Write out database with 1 new entries
Data Base Updated

newcert.pem に署名された証明書がはき出される。

とりあえず、derに変換して、Windowsの署名ビューアで開いてみる。

$ openssl x509 -in newcert.pem -outform der -out server.cer
$ cygstart server.cer

「情報不足のため、この証明書を検証できません。」と出る。

オレオレ証明書には既知の認証局の署名がなく信頼に足らないので検証できなくても正常。

WEBサーバに証明書を設定してみる。

httpd.conf で mod_ssl モジュールを有効にする。
デフォルト設定でキャッシュ使うようになっているので mod_socache_shmcb も読み込む。*1

$ vim conf/httpd.conf
LoadModule socache_shmcb_module modules/mod_socache_shmcb.so
LoadModule ssl_module modules/mod_ssl.so
Include "conf/extra/httpd-ssl.conf"

SSL関係の設定ファイル。↑からIncludeされてる

秘密鍵と証明書ファイルをconfにコピーしてパスを書く。

$ vim conf/extra/httpd-ssl.conf
SSLCertificateFile "/path/to/apache2/conf/server.cer" ← newcert.pem 名前変えておいた
SSLCertificateKeyFile "/path/to/apache2/conf/server.key" ← newkey.pem 名前変えておいた

他の設定方法の説明は詳しいサイトに譲る……。
調べてみると便利なものがあるようなので参考にした。
https://mozilla.github.io/server-side-tls/ssl-config-generator/


apacheを再起動すると、パスフレーズの入力を求められる。
openssl rsa コマンドでパスフレーズなしのキーファイルにするか、
パスフレーズを標準出力に出力する、chmod 700 のスクリプトを用意してSSLPassPhraseDialogで指定すればいいようだ。
echo 'パスフレーズ' でもいいし、 なんかopensslコマンドで適当に暗号化したファイルの中身をはき出すでもいいかもしれない。

SSLPassPhraseDialog exec:/path/to/script.sh

とりあえずhttpsで繋がるようにはなった。

よくわからない証明書を提示されたブラウザは、
ユーザに警告画面を表示する。

*1 : しないとhttpd起動時にSSLSessionCache: 'shmcb' session cache not supported (known names: ). Maybe you need to load the appropriate socache module (mod_socache_shmcb?). エラーになる

ルートCA証明書をWindowsにインストールしてみる。

最初に作ったルートCAの証明書をWindowsの証明書ビューアで開いてみる。

$ openssl x509 -in demoCA/cacert.pem -outform der -out rootCA.cer
$ cygstart rootCA.cer

「このCAルート証明書は信頼されていません。」と出る。

「証明書のインストール」ボタン
→「現在のユーザ」→「次へ」
→「証明書をすべてのストアに配置する」→「参照」→「信頼されたルート証明機関」→「次へ」
→「完了」
セキュリティ警告 ダイアログが出る。意味を理解した上で「はい」をクリックすると、
先ほど作成したルートCAの証明書がインストールされる。
「正しくインポートされました」
一度証明書ビューアを閉じて再度開くと、証明書の目的などが表示されてエラー状態ではなくなる。

$ cygstart rootCA.cer

ルート認証局が信頼されたので、その署名を持つサーバ用の証明書もエラー状態ではなくなっているはずなので確認する。

$ cygstart server.cer

ルート証明書をインストールした状態で、
IEやChromeなどのブラウザからhttpsアクセスをした場合、
警告画面が出ず、ページが表示されるようになる。
※FirefoxはWindowsの証明書ストアを使わないので、別途設定しないといけないはず(使ってないので知らない)

ひとまずここまで。