RSA 鍵で作成した証明書の場合、証明書内の公開鍵と秘密鍵は同一のモジュロ(Modulus)を持っているので、これを比較します。
openssl x509 -noout -modulus -in certificate_file.pem
openssl rsa -noout -modulus -in private_key.pem
openssl req -noout -modulus -in cert_request.pem
これらの実行結果として表示されるモジュロはかなり長くなるので、更に MD5 ダイジェストを計算した法が比較は簡単になります。
openssl x509 -noout -modulus -in certificate_file.pem | openssl md5 openssl rsa -noout -modulus -in private_key.pem | openssl md5 openssl req -noout -modulus -in cert_request.pem | openssl md5]]>
VeriSign のAuthenticode用の証明書を使っています。 これは .exe や .cab ファイルなどにコードサイニングを行うためのマイクロソフトの仕様に沿った証明書で、昔は ActiveX 専用なイメージでしたが、最近は IE がファイルをダウンロードする時にも検証されるので、それなりに重要なものだったりします。
基本的に証明書の有効性は証明書自身の有効期間の間しか確認できません。(その為の有効期間なわけですから当然ですが) しかし、例えばインストーラを作成してウェブに公開するような時に、コードサイン用証明書の有効期限が切れて更新するたびに、公開している全てのファイルに対して署名をやり直すのは大変です。
こういった事にならないように、通常は署名時にタイムスタンプを付けておきます。タイムスタンプは「あるファイルがタイムスタンプをつけた時点で存在し、タイムスタンプをつけてからは変更されていない」事を証明するためのサービスで、デジタル署名にタイムスタンプがついている場合は、署名した証明書の有効期限が過ぎた後も、有効性を確認することができます。
ただ、タイムスタンプ自身も電子署名の一種なので、証明書の有効期限が存在します。この有効期限を過ぎるとタイムスタンプの有効性が確認できなくなるので、有効期間の残りが少なくなってくると意味がなくなってしまいます。
ようやく本題。
VeriSign でも http://timestamp.verisign.com/scripts/timstamp.dll というURLでタイムスタンプサーバを 公開していているのですが、そこでタイムスタンプの署名に使われる証明書の有効期限は以下のようになっています。
真ん中の画像の「VeriSign Time Stamping Services Signer – G2」がタイムスタンプ用の証明書で、有効期限は 2007/06/05 から 2012/06/15 までとなっています。
これを書いているのが、2010/07/31 なので、もう残りが2年ない。。。
有効期限の残りが2年を切る前に流石に更新されるか、少なくともロードマップのアナウンスがあるかと思ってたんですが、何もなかったんですよね。
元から有効期限が5年しかないので、毎年更新するくらいでちょうどいいと思うんですが。
]]>TLSやSSLを使ったウェブサーバーでは一般的には仮想ホストは使えない、という事になっています(何事にも例外はありますが。)仮想ホストは HTTP のリクエストヘッダの Host フィールドの値を元に振り分けられますが,HTTPのリクエストを出すよりも手前の TLS/SSL のハンドシェイク時にサーバ証明書の検証が行われるので,クライアントが接続しようとしているホスト名とサーバ証明書のホスト名が異なってしまい,不正な証明書と表示されてしまいます。
SNIは接続しようとしているホスト名を、クライアントからサーバに伝えるための仕様です。(ホスト名はハンドシェイク前に伝えないと行けないので、平文で送られる事になりますが。。。)これ自体は素晴らしいのですが,Windows XP の IE がサポートしていないので今ひとつ広まっていません。
まずは SNI を使わないで仮想ホストを設定する場合の例です。
ssl_certificate server_cert.pem; ssl_certificate_key server_cer.key; server { port 443; ssl on; server_name host1.example.com; } server { port 443; ssl on; server_name host2.example.co.jp; }
サーバ証明書は1枚しか指定できないので,server_cert.pem には host1.example.com と host2.exacmple.co.jp の双方が記述されている必要があります。ホストが同一のドメインに存在する場合はワイルドカード証明書を使う方法もありますが,例のようにドメインが異なる場合は双方のホスト名をCNもしくはsubjectAltNameに記述します。この方法では仮想ホストが増える場合は証明書を発行し直す必要があります。
次に SNI を使う場合の例です。
server { port 443; ssl on; ssl_certificate host1.example.com.pem; ssl_certificate_key host1.example.com.key; server_name host1.example.com; } server { port 443; ssl on; server_name host2.example.co.jp; ssl_certificate host2.example.co.jp.pem; ssl_certificate_key host2.example.co.jp.key; }
仮想ホスト毎に証明書が指定する事ができるようになります。
実際に SNI をサポートしている Firefox などのブラウザでアクセスすると、それぞれ異なる証明書を持つ事が確認できます。
ただ、現在の nginx に固有の問題かもしれませんが,仮想ホスト毎にクライアント証明書による認証の有無を切り替えるのは出来ないみたいです。ssl_verify_client off;な設定の仮想ホストが1つでもあると,クライアント認証を行う仮想ホストに対してもクライアント証明書が送られません。
クライアント認証が必要ない仮想ホストに対してもssl_verify_client optional;を指定すると大丈夫なようですが。(Nginx の Wikiの説明ではoptional ではなく、askになっているので注意が必要です。)
]]>「政府機関及び金融機関のSSLサーバ暗号設定に関する調査結果について」という講演で興味深い調査結果が発表されていました。
https でサービスを提供している政府系や金融系のWebサーバーに関して、「サポートしている暗号アルゴリズム」と「実際に使用される暗号アルゴリズム」を調査したとの事ですが、ちょっと驚く結果になっていました。
曰く、調査したWebサーバのうち7割以上が新しいアルゴリズムである AES256-SHA をサポートしていますが、XP 上の IE7 では9割弱のサーバに対して比較的古くて問題の見つかっている RC4-MD5 で接続してしまうそうです。Firefox では AES256-SHA が最も多く、Vista の IE7 では AES128-SHA が最も多い結果となっていました。(Vistaでの結果も謎で AES256 が有効でも AES128 を優先して使う。)
SSL(TLS)では、サーバとクライアントがそれぞれ自分がサポートしている暗号アルゴリズムのリストを相手に示して、お互いにサポートしているアルゴリズムの中から実際に使用するものを決定します。このネゴシエーションでは「互いにサポートするアルゴリズムのうち最も暗号強度の高いアルゴリズム」が選択されるものだとばかり思っていたので、実際にはアルゴリズムの優先順位は暗号の強度とは無関係に決まっているみたいです。(IE の場合。Firefox では暗号強度の高い順になっている。)
Windows XP 用の CNG を用意しなかったマイクロソフトの判断は、今となっては間違っていたって事なんでしょうね。(2010年問題はネットブックには影響しないからいいのかな。)
もう一つ驚いたのが、SSL2.0 をサポートするサーバの数で、金融系では3割程度ですが(それでも予想よりはずっと多い)、政府系では6割程度がまだサポートしている、と。
昨年仕事で関わったサーバがユーザーの強い希望で SSL 2.0 を有効にしたのをちょっと思い出してしまいましたが、半年前の調査との比較で「AESを有効にしたらSSL 2.0も有効になった」サーバがかなりあるそうなので、誰も深く考えていないだけなのかもしれません。
]]>