はじめに
ブログの記事をどう書けばいいかわからない、という悩みのように、「SSL/TLSのネゴシエーションって何だろう?」という疑問をもっていませんか?本章では、この記事全体の目的と構成、読むことで得られることを分かりやすく説明します。
本記事の目的
本記事は、クライアント(例:ブラウザ)とサーバーが安全な通信を始めるときに行う「ネゴシエーション(交渉)」の仕組みを体系的に解説します。専門的な用語は必要最小限にし、具体例と図でイメージしやすく説明します。運用やトラブル対応に役立つ実践的な情報も載せます。
誰に向けた記事か
- ウェブ管理者や開発者で、通信がうまくいかないときの原因を知りたい方
- セキュリティの基本を実務で確認したい運用担当者
- 技術の全体像を短時間でつかみたい方
この記事の構成(全8章)
- はじめに(本章)
- SSL/TLSネゴシエーションとは
- ネゴシエーションの流れ:TLSハンドシェイク
- 暗号スイートの選定と表記
- バージョンネゴシエーションと失敗例
- ネゴシエーションの確認・トラブルシューティング
- 実用例・運用上の注意
- 参考:主な用語の解説
読み方のポイント
章ごとに独立して読めるように書きます。まずは2章で概要をつかみ、具体的な手順や確認方法は3章以降を順に読むことをおすすめします。実務で使うコマンド例やよくある失敗例も用意しています。
SSL/TLSネゴシエーションとは
「ウェブサイトが安全に通信している」と聞いても、仕組みがわからないことはありませんか? SSL/TLSネゴシエーションは、クライアント(例:ブラウザ)とサーバーが暗号化された通信路を作るための『交渉』です。両者が使える暗号方式やプロトコルのバージョンを決め、認証や共通鍵の受け渡しを行います。
なぜ必要か
安全な通信では、通信内容を盗み見されたり改ざんされたりしないことが重要です。クライアントとサーバーが同じ方法で暗号化・復号できないと意味がありません。ネゴシエーションは、双方が共通の方法を見つけるための手続きです。
主な要素(わかりやすく)
- TLSバージョン:どの規格を使うかの決定です。新しいほど安全ですが、古い機器は対応しないことがあります。
- 暗号スイート:暗号化、認証、鍵交換の組み合わせです。例として、データを暗号化する方式と鍵を交換する方式などがあります。
- 証明書:サーバーが本物か確認するための電子的な身分証明書です。
- 鍵交換:共通の暗号鍵を安全に共有する仕組みです。
高レベルの流れ(簡単に)
- クライアントが「私はこれを使えます」と候補を送る。
- サーバーが候補から一つ選ぶ。
- 証明書でサーバーを確認し、鍵交換で共通鍵を作る。
- 完了の合図を送り、安全な通信が始まる。
よくある誤解
ネゴシエーションは単なる設定合わせではなく、認証や鍵の安全な受け渡しも含みます。見た目は短いやりとりでも、重要な安全確認が行われます。
次章では、このネゴシエーションの中身を詳しく、TLSハンドシェイクの流れとして順を追って説明します。
ネゴシエーションの流れ:TLSハンドシェイク
概要
TLSハンドシェイクは、通信相手と安全な鍵を決める会話です。まずTCPで通路を作り、次にTLSのやりとりで暗号設定や証明書、共通鍵を決定します。
1. TCPの準備
最初にTCPの3ウェイハンドシェイク(SYN→SYN-ACK→ACK)で接続を確立します。ここで通信路ができてからTLSが始まります。
2. Client Hello(クライアントの提案)
クライアントは使えるTLSのバージョンや暗号の一覧(暗号スイート)、乱数を送ります。例えると「どんな言葉で話せるか」を提示する場面です。
3. Server Hello(サーバーの選択)
サーバーは共通の設定から一つを選び、サーバー側の乱数を返します。さらに通常はサーバー証明書を送って身元を示します。
4. 証明書の検証と鍵交換
クライアントは証明書の発行者や有効期限、ホスト名などを確認します。確認が取れれば、共通鍵を安全に決めるための情報(公開鍵や一時鍵交換の値)をやり取りします。ここで前方秘匿(Forward Secrecy)を実現する方式が使われることが多いです。
5. 完了メッセージと暗号化通信の開始
双方が鍵を確定すると、Finishedメッセージで整合性を確かめます。問題なければ以降の通信は決めた暗号で暗号化され、安全なやり取りが始まります。
暗号スイート(Cipher Suite)の選定と表記
暗号スイートとは
暗号スイートは「鍵交換方式」「認証方式(証明書の種類)」「暗号化アルゴリズム」「メッセージ認証(ハッシュ)」の組み合わせを指します。表記はツールや仕様で異なりますが、実際にはこれらをセットで選びます。
表記の例と違い
- OpenSSL形式:ECDHE-ECDSA-AES256-GCM-SHA384
- IANA形式:TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
両者は同じ組み合わせを示します。OpenSSLは短め、IANAは正式名称に近い表記です。
ネゴシエーションでの選定方法
クライアントはClient Helloで複数候補を送ります。サーバーは自分の設定や対応状況を照らし合わせ、1つ選んで応答します。サーバー側で優先順を設定でき、互換性重視か安全性重視かで順番を変えます。
選定時のポイント(実務的な視点)
- 前方秘匿性(ECDHEなど)を優先すると安全性が高まります。
- AEAD(AES-GCMやChaCha20-Poly1305)を使うと暗号と認証を同時に安全に行えます。
- 鍵長は長いほど安全ですが、性能とのバランスを考えます。
- サーバー証明書の種類(RSAかECDSAか)と暗号スイートの互換性を確認します。
実際の確認方法
- WiresharkでClient Helloを見れば候補一覧が分かります。
- OpenSSLのコマンド(openssl ciphers)でサポート表を確認できます。
- 製品ごとに名前が異なるため、対応表やベンダー資料でマッピングを確認してください。
注意点
古いアルゴリズム(RC4、DES、MD5など)は避けるべきです。互換性確保と安全性向上の両方を見て、サーバー側で優先順位を明確に設定してください。
バージョンネゴシエーションと失敗例
仕組み
クライアントとサーバーは互いに対応可能なTLSバージョンを提示し、共通のうち「最も高い」バージョンを採用します。TLS1.3では”supported_versions”拡張で候補を送り、サーバーが一つを選びます。TLS1.2以前は古い方式のフィールドを使います。
失敗しやすい例
- 例1:クライアントの最大がTLS1.2、サーバーの最小がTLS1.3
共通バージョンがないためハンドシェイクは失敗します。 - 例2:サーバーがTLS1.3専用に設定、古いクライアントがTLS1.2までしか対応していない
接続できません。 - 例3:中間機器がClientHelloの新バージョンを理解できず破棄する(バージョン不耐性)
確認と対処
- opensslで接続テスト: openssl s_client -connect host:443 -tls1_2 / -tls1_3
- サーバー設定を確認し、必要なら一時的に下位互換を許可する
- クライアントを更新して新しいバージョンをサポートさせる
- パケットキャプチャでClientHello/ServerHelloとTLSアラート(protocol_version)を確認する
- 暗号スイートの制約でバージョンが使えない場合があるので合わせて確認してください。
ネゴシエーションの確認・トラブルシューティング
確認の準備
まず通信をキャプチャする環境を用意します。端末でWiresharkを起動し、問題の通信を再現してパケットを取得します。ログ保存を忘れないでください。
Wiresharkで見るポイント
- Client Hello/Server Hello:TLSバージョンとクライアントが提示した暗号スイート一覧を確認します。
- Certificate:証明書チェーンが正しく送信されているか、失効や期限切れがないかをチェックします。
- Alertメッセージ:Handshake Failureなどのアラートは失敗箇所の手がかりになります。
- Follow TLS Stream:一連のハンドシェイクを時系列で追えます。
ログとキーワードの調査
SSL-VPNやサーバのログで「TLSv1.2」「handshake failed」「cipher」といったキーワードを検索します。ログには失敗理由やポリシー違反の記録が残ることが多いです。
失敗箇所の特定手順
- クライアントとサーバの提示するTLSバージョン・暗号スイートを比較します。合致しなければ交渉で失敗します。
- 証明書チェーンとCAの信頼設定を確認します。中間証明書の不足で失敗することがあります。
- 中間機器(ロードバランサ、プロキシ、ファイアウォール)の干渉を疑います。ログや設定を確認してください。
よくある原因と対処
- 暗号スイート不一致:サーバまたはクライアントで許可するスイートを調整します。
- バージョンミスマッチ:TLSバージョンの許可ポリシーを見直します。
- 証明書問題:期限切れやチェーン不備は更新・追加で対処します。
製品ごとの確認とサポート
製品によっては独自のポリシーや制限があります。ベンダーのドキュメントやサポート窓口で、ログの読み方や既知の制限を確認してください。
必要ならopensslのs_clientなどで再現試験を行い、最低限の情報で問題点を切り分けてください。
実用例・運用上の注意
導入の実例
小規模ウェブサイトでは、まずTLS 1.2以上をサポートし、サーバー側で暗号スイートを厳選します。例:ECDHE + AES-GCMを優先する設定にして、互換性のために一時的に古いTLSは残す場合があります。
互換性の考え方
クライアントによって対応バージョンや暗号が異なります。最新のブラウザはTLS 1.3を使えますが、古い端末は1.0/1.1しか対応しないことがあります。利用者層を確認して、段階的に強化してください。
設定のポイント
- サーバー優先の暗号順序を有効にする。
- 安全な暗号(例:ECDHE+AES-GCM)を上位に配置する。
- 期限切れ証明書や弱い鍵長を避ける。
トラブル発生時の対応
- ログ(サーバー証明書エラー、ハンドシェイク失敗)をまず確認する。
- openssl s_client やブラウザの開発ツールで接続を試す。
- 必要ならパケットキャプチャ(tcpdump/Wireshark)でハンドシェイクを解析する。これにより、どちらがネゴシエーションを拒否したか分かります。
運用上の注意
定期的に暗号方針と証明書を見直してください。段階的なロールアウトとバックアップ計画を用意すると、安全に強化できます。
参考:主な用語の解説
以下はTLS/SSLとネゴシエーションに関する主要な用語を、やさしく説明したものです。
TLS/SSL
通信を暗号化し、相手の正当性を確認する仕組みです。例:ウェブブラウザでHTTPSを使うと、通信が第三者に読まれにくくなります。
ネゴシエーション
通信開始時に、どの暗号方式やバージョンを使うかを決めるやり取りです。双方が使える方式を合わせて選びます。
暗号スイート(Cipher Suite)
暗号化・鍵交換・認証・ハッシュの組み合わせです。例:AESで暗号化、ECDHEで鍵交換、SHAで整合性確認、というようにセットで指定します。
ハンドシェイク
安全な通信路を作る最初の一連のやり取りです。鍵の決定や証明書の確認を行います。ハンドシェイクが終わると暗号化された通信が始まります。
証明書と認証局(CA)
証明書はサーバーの身元を示すデジタル文書です。認証局(CA)がその正当性を保証します。ブラウザはCAの署名を検証して接続先を信頼します。
公開鍵/秘密鍵
公開鍵は誰でも使える鍵で、秘密鍵はサーバーだけが持ちます。公開鍵で暗号化した情報は対応する秘密鍵で復号します。
鍵交換(Key Exchange)
通信ごとに使う共通鍵を安全に決める手続きです。例:ECDHEは短時間用の鍵を安全に共有し、後から解読されにくくします(PFS)。
セッション再開
既に確立したセッション情報を使って、再接続を速く安全に行う仕組みです。
SNI(Server Name Indication)
1つのIPアドレスで複数のドメインを運用する際、接続時にどのホスト名に接続するかを通知する拡張です。
証明書失効(CRL/OCSP)
証明書が無効になったときにその情報を確認する仕組みです。盗難や交換時に重要です。
主なアルゴリズム名(例)
- RSA:古くからある認証・鍵交換方式
- ECDHE:短期鍵交換でPFSを提供
- AES-GCM:高速で安全な暗号と整合性検査を同時に行う方式
用語は実際の設定やログを見ながら覚えると理解が早まります。わかりにくい用語があれば、個別に説明します。