Transport Layer Security
第二フェーズではサーバからクライアントに対して鍵共有に必要な情報を送る。具体的にはサーバはCertificate、ServerKeyExchange、CertificateRequest、ServerHelloDoneを(第一フェーズServerHelloに引き続き)クライアントに送信する。
Certificateは鍵共有で用いる公開鍵とその証明書で別途取り決めがない限りX.509v3のフォーマットに従う。なお鍵共有方式としてDH_anonを用いている場合にはcertificateは必要ない。
ServerKeyExchangeは鍵共有プロトコルに依存して送るデータが異なるが、DH_anonであれば、g mod pという形のデータを送る。ここでxはサーバの秘密の乱数である。鍵共有プロトコルがDHE_DSS、DHE_RSA、DH_anonでは何らかのserver_key_exchangeを送るが、RSA、DH_DSS、DH_RSAでは何も送らない。
CertificateRequestはクライアントの公開鍵とその証明書を送ることを要求するためのもので、サーバが許容できる証明書の種別、ハッシュと署名方式、および認証局のリストからなっている。
そして最後にサーバ側からのメッセージ送信が終わった事を示すServerHelloDoneをクライアントに送る。
TLS/SSLライブラリの多くはオープンソースソフトウェアである。
TLSは公開鍵証明書を用いて認証を行い、なりすましを極力排除しようとする。しかしシステムの自動的な対応には限界があり、すべてのなりすましを検出できるわけではない。
公開鍵証明書には認証局による電子署名が与えられる。その署名の正当性を評価するためには認証局の証明書が必要であり、最終的にはルート証明書と呼ばれる一群の証明書に行きつく。各システムは、認証局の証明書として信用できるルート証明書を、あらかじめ保持している。認証局は自身の秘密鍵を厳重に秘匿し、また証明書の発行にあたっては正当なサーバ管理者かどうか確認することが求められる。これらが保証されない認証局のルート証明書を組み込むことは、TLSにおける認証機能を破綻させることになる。仮に認証局自体は安全でも、入手したルート証明書が本当に意図する認証局のものかどうか判断することは難しいという点も注意すべきである。
TLSで認証を行うためには、認証局の署名に加えて、証明書の発行先を確認する必要がある。確認しない場合、サーバAの管理権限を持たない者がサーバBとして正当な証明書を取得し、その証明書を使ってサーバAを名乗ることができてしまう。TLS用のサーバ証明書には発行先サーバのホスト名が書き込まれており、クライアントは自分が接続しようとしているサーバのホスト名と一致するかどうか確認することができる。
現実には「正当な」サーバであっても、これらの検証において「問題がある」と判断される証明書を使って運用されているサーバが少なからず存在する。セキュリティ研究者の高木浩光は、このような証明書のことを、オレオレ詐欺をもじって「オレオレ証明書」と呼んで批判している。
本説ではTLS 1.2の概要を説明する。
TLSには主なプロトコルとして暗号通信に必要な鍵 (master secret) を鍵共有してセッションを確立するTLSハンドシェイクプロトコルと、master secretを用いて暗号通信することで確立されたセッションにおけるコネクションをセキュアにするTLSレコードプロトコルがある。
その他に用いている暗号方式やハッシュ関数等のアルゴリズムを変更する Change Cipher Spec プロトコルと通信相手からの通信終了要求や何らかのエラーを通知する アラートプロトコルがある。
第一のフェーズではサーバ・クライアント間で通信に必要情報の合意を図る。このフェーズでは、まずクライアントからサーバにClientHelloが送信され、次にサーバからクライアントにServerHelloが送信される。
ClientHelloはTLSのバージョン、乱数、セッションID、通信に用いる暗号方式やハッシュアルゴリズムのリスト (cipher_suites)、通信内容の圧縮方法、および拡張領域の6つからなる。乱数は鍵共有におけるリプレイ攻撃を防ぐためのものである。
ServerHelloもClientHelloと同様の6つからなっている(名称は一部異なる)。ServerHelloの主な目的は、ClientHelloで提示された選択肢の中でサーバにとって好ましいものを選択する事で、例えばClientHelloで提示されたcipher_suitesの中から、サーバが通信に使いたいcipher_suiteを一組選ぶ。乱数はClientHelloとは独立して選ぶ。これもリプレイ攻撃を回避するためである。セッションIDは特に問題がなければClientHelloと同一のものを返す。