opensslとcurlでクライアント証明書を使ってHTTPS接続する

1年ぶりにやったらど忘れしてる。

クライアント証明書発行

事前にプライベートCA作っておくこと 詳細は省略

/etc/pki/tls/misc/CA -newca
クライアント証明書用 秘密鍵CSR作成
/etc/pki/tls/misc/CA -newreq

上で作ったファイルがあるディレクトリでCAで署名

/etc/pki/tls/misc/CA -sign

配布用にPKCS#12ファイル作成

openssl pkcs12 -export -clcerts -inkey newkey.pem -in newcert.pem \
  -certfile /etc/pki/CA/cacert.pem -out username.p12

証明書失効

openssl ca -revoke /path/to/newcert.pem
openssl ca -gencrl -out /etc/pki/CA/crl/crl.pem
## 確認
openssl crl -in /etc/pki/CA/crl/crl.pem -text

web上ではrevokeとgencrlを同時にやっている例があったが、自分の環境だと、同時に実行するとcrlは確かに出力されるが、
revokeで指定した証明書は失効状態にならなかった。なのでrevokeしたあとにgencrlするようにしている。

おまけ: pkcs12から証明書、鍵を抜き出す

鍵を暗号化せず出力する場合は-nodesをつける。

CA証明書だけ抜きだす

$ openssl pkcs12 -in file.p12 -out ca.pem -cacerts -nokeys

鍵付き証明書を抜き出す

$ openssl pkcs12 -in file.p12 -out cert.pem -clcerts

証明書だけ抜き出す

$ openssl pkcs12 -in file.p12 -out cert.pem -clcerts -nokeys

鍵だけ抜き出す

$ openssl pkcs12 -in file.p12 -out key.pem -nocerts

クライアント証明書を使って接続確認

curl の-Eオプション使うのが簡単

$ curl https://ssl.example.com -E file.p12:password

備考: -Eでpkcsが使えるのは手元の環境だとmaccurlのみだった

linux CentOS6

centosのmanはpemじゃないとダメと書いてたのでp12から証明書だけ抜きだす

  • 暗号化して鍵を出力した場合
$ openssl pkcs12 -in file.p12 -out cert.pem -clcerts

CentOS5の場合は問題なし

## 引数にpassword
$ curl https://ssl.example.com -E ./cert.pem:password
## もしくは対話式で入力
$ curl https://ssl.example.com -E ./cert.pem

CentOS6の場合
手元の環境で確認した場合、暗号化してたらダメだった。。。

$ curl https://ssl.example.com/ -E ./cert.pem:password
curl: (35) NSS: client certificate not found: ./cert.pem
## 証明書と鍵を分離してもダメ。
$ curl https://ssl.example.com/ -E ./cert.pem:password --key key.pem

こういわれる。同じ鍵、証明書を使ってwgetするといけたので鍵、証明書は問題ないはず。

$ wget --certificate=cert.pem --private-key=key.pem https://ssl.example.com/

ここに同じこと書いてた。stackoverflow.com

  • 暗号化せず鍵を出力した場合
$ openssl pkcs12 -in file.p12 -out cert.pem -nodes -clcerts

CentOS5の場合はカレントディレクトリのファイルの場合ファイル名だけで良かったけど、
CentOS6の場合はフルパスもしくは相対パスで指定しないとエラーになった。

## ng
$ curl https://ssl.example.com -E cert.pem
curl: (35) NSS: client certificate not found: cert.pem
## ok
$ curl https://ssl.example.com -E ./cert.pem
$ curl https://ssl.example.com -E /path/to/cert.pem

man curlになんかそれぽいこと書いてる。

If curl is built against the NSS SSL library then this option can tell curl
the nickname of the certificate to use within the NSS database defined by
the environment variable SSL_DIR (or by default /etc/pki/nssdb). If the NSS
PEM PKCS#11 module (libnsspem.so) is available then PEM files may be loaded.
If you want to use a file from the current directory, please precede it with
"./" prefix, in order to avoid confusion with a nickname.