OpenSSL1.0.0で楕円曲線志向なCAを立てる

楕円曲線を用いた暗号方式でCAの証明書を作ろう、というお話。OpenSSLは1.0.0から楕円曲線暗号ECC)への対応がきちんとしてきているのだけど、ディストリ付属のOpenSSLは古い(0.9.8)ことがある。$ openssl version とコマンド打てば使っているopensslのバージョンが分かるので、古いようだったら新しいモノを入れると幸せになれる。

環境:FreeBSD 8.1-RELEASE, opensslはportsから入れる

準備

# cat /usr/ports/security/openssl/distinfo | head -1
SHA256 (openssl-1.0.0d/openssl-1.0.0d.tar.gz) = 92511d1f0caaa298dba250426f8e7d5d00b271847886d1adc62422778d6320db
# portinstall security/openssl
# cp /usr/local/openssl/openssl.cnf.sample /usr/local/openssl/openssl.cnf
# rehash
# openssl version
OpenSSL 0.9.8n 24 Mar 2010
# which openssl
/usr/bin/openssl

portsからインストールしてもopensslのバージョンは1.0.0dにならない。これは/usr/bin/opensslが使われているから。
そこで、/usr/bin/opensslの実行権限を落としてしまう。良い方法かは怪しいけど、ファイル名を変えるよかマシ。

# chmod -x /usr/bin/openssl
# rehash
# openssl version
OpenSSL 1.0.0d 8 Feb 2011

無事1.0.0dになりました。

CAの鍵対を準備する

# openssl ecparam -list_curves
(略)
  sect233r1 : NIST/SECG/WTLS curve over a 233 bit binary field
  sect239k1 : SECG curve over a 239 bit binary field
  sect283k1 : NIST/SECG curve over a 283 bit binary field
(略)
# openssl ecparam -genkey -name prime256v1 -out cakey.pem

曲線については、http://www.secg.org/download/aid-784/sec2-v2.pdfを参照するに、list_curvesにて出てくる曲線のだいたいがexplicitly recommendedらしい。ただしsect239k1などの一部の曲線は様々な標準に準拠こそしているがrecommendedではないので*1、鍵対を作る前に曲線の準拠具合をチェックしておくべき。
で、2011年2月現在の調査結果*2によると、現段階でWindowsにて実装されているのはprime256v1, secp384r1, secp521r1の三種類のみらしい*3
あとは、現在のところ楕円曲線の有効な攻撃法は見つかっていないはずなので、bit数を基準に選ぶ。160bitがRSA1024bitと同様の強度とされているので、2048bitに対応するのは224くらいだろうか、ということでprime256v1を選んでみる。


cakey.pemが鍵対ファイル。読むときはこんな感じ:

# openssl ec -in cakey.pem -text -noout

CAの自己署名証明書を作成する

# openssl req -new -x509 -days 1826 -sha256 -key cakey.pem -out cacert.cer
# openssl x509 -text -noout -in cacert.cer

0.9.8dではsha1しか対応していなかったが、1.0.0bではsha256でサインできるようになっている。1826日はだいたい5年。これで自己署名証明書ができた。
鍵対と証明書との対応を確認するさい、RSAのときにはmodulusを比較したが、ecdsaの場合は上記x509の出力結果のpubの部分とecの出力結果のpubの部分が同じになっていればok。

自己署名ではなくCSR(証明書署名要求)を作る場合は以下のようなコマンド。pkcs形式なのでverisignに送るときも安心*4

# openssl req -new -key cakey.pem -out careq.csr
# openssl req -in careq.csr -text -noout

それを自分でサインするなら:

# openssl x509 -req -in careq.csr -signkey cakey.pem -out cacert.cer -days 1826

CAの諸設定

  • openssl.cfgの初期設定ではCAの場所が./demoCAとなっていてとても怪しいので、まずこれをどこかの絶対パスに変更する(例:/var/ssl/CA)
  • 各種ディレクトリを作る
    • certs, crl, newcerts
  • ファイルをtouchする
    • index.txt, serial
  • ファイルの中身を作る
    • serialに「01」と書く
# vi /usr/local/openssl/openssl.cfg
(略; [CA_default]のdir項目を絶対パスにする等)
# mkdir -p /var/ssl/CA
# cd /var/ssl/CA
# mkdir certs crl newcerts
# touch index.txt serial
# cat > serial
01
^D(ctrl-Dで入力終了)

これで最低限動くようになる。より心地よい設計は今後の課題。

参考サイトさん:
http://webframe.sourceforge.jp/wiki/index.php?OpenSSL%A4%CB%A4%E8%A4%EB%C2%CA%B1%DF%B6%CA%C0%FE%B0%C5%B9%E6%A4%CE%CD%F8%CD%D1
http://researchmap.jp/index.php?action=cv_download_main&upload_id=11085
http://cro-pel.com/modules/penguin/content0103.html
http://www.fc-lab.com/network/server/pki/openssl.html

*1:IPSecにおいては準拠ですらない

*2:http://researchmap.jp/index.php?action=cv_download_main&upload_id=11085

*3:sect283k1で試したところ、確かにダメっぽかった

*4:https://www.verisign.co.jp/ssl/about/pem.html