TLS 1.2のSignature Algorithms extension

GoogleMicrosoftが、将来的に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で新たに加わったものであり、それ以前のものではこのパラメータを付加しても無視されます。


ChromeTLSハンドシェイクを実際に確認すると、ClientHelloにSignature Algorithms extensionextension が付いていることが確認できる。

実際に試す

Apacheサーバでは、RSAECCで署名した証明書を出し分ける事が出来る。


confファイルに、RSAECCで署名されたサーバ証明書と鍵をそれぞれ記述するだけである。


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


実際に確認してみても、ちゃんと指定されている。

ただしSHA-1,SHA-2の出し分けは...

SHA-1:RSAとSHA-2:RSAの証明書をapache2.confに指定して起動しようとすると起動しない...

 [ssl:emerg] [pid 8633:tid 140488422037376] AH02242: Init: Multiple RSA server certificates not allowed