GoogleやMicrosoftが、将来的にSHA-1を使用した署名の証明書を安全なものとして扱わないとするアナウンスは、記憶に新しいかと思います。
このアナウンスを受けて認証局各社ともSHA-2への移行を薦めている。
さて、仮にクライアントがSHA-2に対応していない場合はどうなるのでしょうか?サーバは証明書を出し分けたり出来るのでしょうか?
(実装はともかくして)TLS1.2より、ハンドシェイク時にクライアントのサポートしてる署名アルゴリズムを伝えられるようです。
Signature Algorithms
Signature Algorithms extension はRFC5246の7.4.1.4.1.で定義されている。
TLSのハンドシェイク時にClientHelloの中で、
クライアントはサーバにサポートしている署名アルゴリズムを伝えることが出来る。
この署名アルゴリズムは、サーバから送られるメッセージ(サーバ証明書や鍵交換)の検証に使うものである。
このSignature Algorithms extensionextension はTLS1.2で新たに加わったものであり、それ以前のものではこのパラメータを付加しても無視されます。
ChromeのTLSハンドシェイクを実際に確認すると、ClientHelloにSignature Algorithms extensionextension が付いていることが確認できる。
実際に試す
Apacheサーバでは、RSAとECCで署名した証明書を出し分ける事が出来る。
confファイルに、RSAとECCで署名されたサーバ証明書と鍵をそれぞれ記述するだけである。
apache2.conf
SSLCertificateFile ./rsa.crt SSLCertificateKeyFile ./rsa.key SSLCertificateFile ./ecc.crt SSLCertificateKeyFile ./ecc.key
また、新しめのopensslではs_clientでSignature Algorithms extensionextension を指定することができる。これを使用して、証明書出し分けられている事を確認する。
「-sigalgs」 でアルゴリズムを指定する。
-sigalgs RSA+SHA256:ECDSA+SHA256
$ openssl version OpenSSL 1.0.2-beta3 25 Sep 2014 $ openssl s_client -connect localhost:443 -sigalgs RSA+SHA256 |tee fuga |grep -A1 "BEGIN CERTIFICATE" -----BEGIN CERTIFICATE----- MIICujCCAaKgAwIBAgIJAPL18ljL1SHgMA0GCSqGSIb3DQEBCwUAMBUxEzARBgNV $ openssl s_client -connect localhost:443 -sigalgs ECDSA+SHA256 |tee fuga |grep -A1 "BEGIN CERTIFICATE" -----BEGIN CERTIFICATE----- MIICiTCCAd6gAwIBAgIJANFO0793J5gNMAoGCCqGSM49BAMCMFExCzAJBgNVBAYT