トランスポート・レイヤー・セキュリティ(TLS)プロトコルの概要

トランスポート・レイヤー・セキュリティ(TLS)は、Webで暗号化を実装する場合に最もよく使用されるプロトコルです。 TLSは、ネットワークでセキュアな通信を行うために暗号化プロセスを組み合わせて使用します。 このセクションでは、TLSおよびTLSが使用する暗号化プロセスについて簡単に説明します。

TLSは、インターネット通信で使用される標準的なTCP/IPソケットプロトコルをセキュアに拡張します。 「TCP/IP TLSを使用したプロトコル・スタック」に示すように、トランスポート・レイヤーとアプリケーション・レイヤーの間に、標準のTCP/IPプロトコル・スタックのsecure sockets layerが追加されます。 TLSとともにもっともよく使用されるアプリケーションは、インターネットWebページ用のプロトコルであるHypertext Transfer Protocol (HTTP)です。 この他にも、Net News Transfer Protocol (NNTP)、Telnet、Lightweight Directory Access Protocol (LDAP)、Interactive Message Access Protocol (IMAP)、File Transfer Protocol (FTP)などのアプリケーションがあり、同様にTLSとともに使用します。

TLSを使用するTCP/IPプロトコル

TCP/IPの層 プロトコル
アプリケーション層 HTTP、NNTP、Telnet、FTPなど
Transport Layer Security TLS
伝送制御プロトコル TCP
インターネット層 IP

Secure Socket Layer (SSL)は、1994年にNetscape社によって開発され、インターネットの世界で使用されるようになると、標準的な存在になりました。 現在では、国際的な標準化機構であるInternet Engineering Task Force (IETF)が管理しています。 IETFはSSLの名称をTLSに変更し、1999年1月に最初の仕様のバージョン1.0をリリースしました。 TLS 1.0は、SSLの最新バージョン3.0を少しだけ変更したものです。 このアップグレードでは、前のバージョンでの不具合が修正され、既知の弱いアルゴリズムの使用が禁止されました。 TLS 1.1は2006年4月、TLS 1.2は2008年8月、TLS 1.3は2018年8月にリリースされました。 TLS 1.3はTLSプロトコルを全面的に見直したもので、以前のバージョンよりもセキュリティとパフォーマンスが大幅に向上しています。

TLSの動作

TLSが有効な理由の1つに、複数の暗号化プロセスを使用していることがあります。 TLSは、公開キー暗号化で認証を行い、秘密キー暗号化とハッシュ関数で機密性とデータ整合性を提供します。 TLSについて理解する前に、暗号化の処理方法を理解しておくと役立ちます。

暗号化プロセス

暗号化の主な目的は、2者間の秘密の通信に権限のない第三者がアクセスしたり、その内容を理解するのを困難にすることです。 暗号化のプロセスによって、データに対する権限のないすべてのアクセスを必ずしも制限できるわけではありませんが、権限のない者が秘密のデータを理解できないようにすることができます。 暗号化では、複雑なアルゴリズムを使用して、元のメッセージ(クリアテキスト)をエンコードされたメッセージ(暗号テキスト)に変更します。 ネットワーク上で転送されるデータの暗号化および復号化に使用するアルゴリズムは一般に、秘密キー暗号化と公開キー暗号化の2つのカテゴリに分けられます。

秘密キー暗号化も公開キー暗号化も、合意に基づく暗号キーまたは暗号キーのペアを使用します。 キーは、データの暗号化プロセスおよび復号化プロセスで暗号化アルゴリズムが使用するビット文字列です。 暗号化キーは、錠のキーと同様、錠を開けることができるのは正しいキーのみです。

通信の当事者が互いにキーを安全に送信するのは、些細な問題ではありません。 公開キー証明書を使用すると、公開キーを安全に送信し、受信者に公開キーの信頼性を保証できます。 「公開鍵証明書」を参照してください。

秘密キー暗号化と公開キー暗号化における暗号化処理の説明では、セキュリティのコミュニティで広く使用されている慣例(通信する2人の当事者はAliceとBobという名前で示される)に従います。 権限のない第三者は攻撃者とも呼ばれ、Charlieと名付けられます。

秘密キー暗号化

秘密キー暗号化では、通信するAliceとBobはメッセージの暗号化と復号化に同じキーを使用します。 暗号化されたデータをネットワークで送信する前に、AliceとBobはキーを持っていることが必要で、暗号化と復号化に使用する暗号化アルゴリズムに同意している必要があります

秘密キー暗号化で大きな問題の1つが、攻撃者にアクセスされずに一方から他方にキーを渡す方法の問題です。 AliceとBobが秘密キー暗号化でデータを保護しても、CharlieがそのキーにアクセスできればAliceとBobの間で傍受した秘密メッセージを理解できます。 CharlieはAliceとBobのメッセージを復号化できるだけではなく、Aliceになりすまして暗号化データをBobに送信することもできるのです。 ボブはメッセージがアリスではなくチャーリから来たことを知りません。

秘密鍵配布の問題が解決された後、秘密鍵暗号は貴重なツールとなり得る。 そのアルゴリズムにより、優れたセキュリティと暗号化データが比較的迅速に提供できるからです。 TLSセッションで送信される機密性の高いデータの多くは、秘密キー暗号化で送信されます。

秘密キー暗号化は、データの暗号化と復号化の両方に同じキーを使用するため、対称暗号化とも呼ばれます。 よく知られている秘密キー暗号化アルゴリズムには、Advanced Encryption Standard (AES)、Triple Data Encryption Standard (3DES)およびRivest Cipher 4 (RC4)があります。

公開キー暗号化

公開キー暗号化は、公開キーと秘密キーの両方を使用することでキーの配布方法の問題を解決しました。 公開キーはネットワークを通じて公開し、送信できますが、非公開キーは通信の1人の当事者にしか公開されません。 公開キーと非公開キーは暗号化方式が逆で、一方のキーで暗号化したものをもう一方のキーで復号化します。

Bobが公開キー暗号化を使用して、Aliceに秘密のメッセージを送信するとします。 Aliceは公開キーと非公開キーをどちらも持っているので、非公開キーは安全な場所に保管しておき、公開キーをBobに送信します。 BobはAliceの公開キーを使ってAliceへの秘密のメッセージを暗号化します。 Aliceは非公開キーを使ってメッセージを復号化します。

Aliceが自分の秘密キーを使用してメッセージを暗号化し、その暗号化されたメッセージをBobに送信すれば、Bobが受信するデータはAliceから届いたものだと考えることができます。BobがAliceの公開キーでデータを復号化できれば、そのメッセージはAliceが自分の秘密キーで暗号化したものに間違いなく、Aliceの秘密キーを持っているのはAliceのみです。 問題は、Aliceの公開キーが公開されているために、だれもがメッセージを読めてしまうことです。 このシナリオは、セキュアなデータ通信を考慮に入れていませんが、デジタル署名の基本を示しています。 デジタル署名とは公開キー証明書のコンポーネントの1つで、TLSでクライアントやサーバーを認証するために使用します。 公開キー証明書デジタル署名を参照してください。

公開キー暗号化は、データの暗号化および復号化に様々なキーが使用されるため、asymmetric cryptographyとも呼ばれます。 TLSでよく使われる、よく知られている公開キー暗号化アルゴリズムは、Rivest Shamir Adleman (RSA)アルゴリズムです。 このほかにも、秘密キーを交換するために設計されたTLSを使う公開キー暗号化アルゴリズムには、Diffie-Hellman (DH)があります。 公開キー暗号化には膨大な計算が必要なため、速度が大幅に遅くなります。 そこで、この方式は暗号化データ通信全体に使用するよりもむしろ、秘密キーなど少量のデータを暗号化する場合にだけ使用します。

秘密キー暗号化と公開キー暗号化の比較

秘密キー暗号化と公開キー暗号化のどちらにも、長所と短所があります。 秘密キー暗号化では、データの暗号化や復号化に時間はかかりませんが、通信者同士が同じ秘密キー情報を共有する必要があり、キーの交換の方法が問題になります。 公開キー暗号化では、キーを秘密にする必要がないのでキーの交換は問題になりませんが、データの暗号化と復号化に使用するアルゴリズムには膨大な計算が必要で、著しく遅くなります。

公開鍵証明書

公開キー証明書を使用すると、エンティティは非対称暗号化で使用する公開キーを安全に配布できます。 公開キー証明書は、次の状況を回避します。Charlieが自分の公開キーと秘密キーを作成すれば、自分はAliceだと名乗ってBobに公開キーを送信できます。 BobはCharlieと通信できますが、データをAliceに送信していると思い込んでしまいます。

公開キー証明書は電子的なパスポートだと考えることができます。 これは、信頼できる組織によって発行され、所有者に識別情報を提供します。 公開キー証明書を発行する信頼できる組織を、証明書発行局(CA)と呼びます。 CAは公証人にたとえることができます。 CAから証明書を取得するには、識別情報の証拠となるものを提供する必要があります。 CAは、申請者が申し立てる組織の代表であるとの確証が得られたら、証明書に含まれる情報の妥当性を証明する証明書に署名します。

公開キー証明書には、次のようなフィールドがあります。

発行者
証明書を発行した認証局(CA)。 証明書を発行したCAが信頼でき、証明書が有効であれば、証明書は信頼できます。
有効期限
証明書に有効期限があります。 証明書の有効性を検証する場合は、この日付をチェックしてください。
件名
証明書が表すエンティティに関する情報が含まれます。
サブジェクト公開鍵
証明書が提供する主要な情報は、サブジェクトの公開鍵です。 その他のフィールドは、このキーの妥当性を確認するためのものです。
シグネチャ
証明書は、証明書を発行したCAによってデジタル署名されています。 署名はCAの非公開キーを使って作成され、証明書の妥当性を保証するものです。 証明書のみに署名され、TLSトランザクションで送信されるデータには署名されないため、TLSには非拒否性がありません。

ボブが公開鍵証明書でアリス公開鍵を有効なものとして受け入れた場合、チャールズがアリスとして偽装したときにボブは秘密情報をチャーリに送信することに騙されません。

複数の証明書を証明書チェーンでリンクすることもできます。 証明書チェーンを使用する場合、最初の証明書は必ず送信者の証明書です。 次は送信者の証明書を発行したエンティティの証明書です。 チェーン内に他の証明書がある場合、それぞれ直前の証明書を発行した証明書発行局の証明書です。 チェーンの最後の証明書は、ルートCAの証明書です。 ルートCAは広く信頼されているパブリック認証局です。 複数のルートCAの情報は、通常、クライアントのインターネット・ブラウザに保存されています。 この情報には、CAの公開キーが含まれています。 よく知られているCAには、Comodo、DigiCertおよびGoDaddyなどがあります。

暗号ハッシュ関数

暗号化されたデータを送信する場合、TLSは通常、暗号化ハッシュ関数を使ってデータの整合性を保証します。 ハッシュ関数を使って、AliceがBobに送ったデータをCharlieが改ざんできないようにします。

暗号化ハッシュ関数はチェックサムに似ています。 主な違いは、チェックサムがデータの偶発的変化を検出するのに対し、暗号化ハッシュ関数は故意による変更を検出するように設計されています。 暗号化ハッシュ関数によってデータが処理されると、hashと呼ばれる小さなビット文字列が生成されます。 メッセージがごくわずかだけ変更された場合も、結果として生成されるハッシュは大きく変更されます。 暗号化ハッシュ関数には、暗号化キーが必要ありません。 TLSとともによく使用されるハッシュ関数は、Secure Hash Algorithm (SHA)です。 SHAは、U.S. National Institute of Standards and Technology (NIST)によって提案されました。

メッセージ認証コード

メッセージ認証コード(MAC)は暗号化ハッシュに似ていますが、秘密キーをベースにしている点が異なります。 秘密キー情報が暗号化ハッシュ関数で処理したデータに含まれている場合、その結果生成されるハッシュはHMACと呼ばれます。

Aliceは、BobへのメッセージをCharlieが確実に改ざんしないようにする場合、メッセージのHMACを計算して元のメッセージにHMACを追加できます。 次に、Bobと共有している秘密キーを使用してメッセージとHMACを暗号化できます。 Bobは、メッセージを復号化してHMACを計算すれば、送信中にメッセージが変更されたかどうかを知ることができます。 TLSでは、HMACを使ってセキュアなデータを送信します。

デジタル署名

メッセージに暗号化ハッシュが作成されると、ハッシュは送信者の非公開キーで暗号化されます。 このような暗号化ハッシュをデジタル署名と呼びます。

TLS 1.3ハンドシェーク

TLS 1.3を使用した通信によってTLSハンドシェークが開始されます。 これは、クライアントとサーバー間の初期ネゴシエーションで、TLS内で以降の相互作用のパラメータを確立します。 これは、キー交換、サーバー・パラメータおよび認証という3つのフェーズで構成されます:

  1. Key Exchange: このフェーズでは、共有キーが(楕円曲線グループ (ECDHE)または有限フィールド・グループ (DHE))に属することができる名前付きグループなどの共有キーイング・マテリアルを確立し、対称暗号オプションなどの暗号化パラメータを選択します。

  2. Server Parameters: このフェーズでは、証明書ベースのクライアント認証が必要かどうかなど、その他のハンドシェイク・パラメータが確立されます。

  3. Authentication: このフェーズでは、サーバー(オプションで、クライアント)を認証し、キー確認およびハンドシェイク整合性を提供します。

TLS 1.3プロトコル

次の図に、TLSハンドシェーク全体の一連のメッセージを示します。

完全なTLS 1.3ハンドシェイク
  1. キーの交換:

    1. クライアントは、サーバーにClientHelloメッセージを送信します。

    2. サーバーはClientHelloメッセージを処理し、接続に適した暗号化パラメータを決定します。 その後、ネゴシエーションされた接続パラメータを示す独自のServerHelloメッセージで応答します。 TLS 1.3の場合、ServerHelloメッセージによってキーおよび暗号オプションのみが決定されます。 その他のハンドシェーク・パラメータは、後で決定できます。

  2. サーバー・パラメータ: サーバーは、次の2つのメッセージを送信してサーバー・パラメータを確立します:

    • EncryptedExtensions: このメッセージには、個々の証明書に固有のものを除いて、暗号化パラメータの決定に必要とされないClientHello拡張への応答が含まれています。

    • CertificateRequest (オプション): 証明書ベースのクライアント認証が必要な場合、サーバーはその証明書に必要なパラメータを含むメッセージを送信します。 クライアント認証が不要な場合、このメッセージは省略されます。

  3. 認証:

    1. サーバーは次の認証メッセージを送信します:

      • Certificate (オプション): このメッセージには、認証証明書と、証明書チェーン内のサポートするその他の証明書が含まれます。 サーバーが証明書で認証されていない場合、このメッセージは省略されます。


        ノート: 証明書メッセージには、証明書のかわりにRAWキーを含めることができます。


      • CertificateVerify (オプション): このメッセージには、Certificateメッセージ内の公開キーに対応する秘密キーを使用したハンドシェーク全体に対する署名が含まれています。 サーバーが証明書で認証されていない場合、このメッセージは省略されます。

      • Finished: ハンドシェーク全体のMAC (メッセージ認証コード)。

    2. クライアントは、独自のCertificate、CertificateVerifyおよびFinishedメッセージで応答します。 サーバーがCertificateRequestメッセージを送信しなかった場合、Certificateメッセージは省略されます。 クライアントが証明書で認証されていない場合、CertificateVerifyメッセージは省略されます。

クライアントとサーバーは、アプリケーション・データを相互に安全に送信できるようになりました。

キーの交換

キー交換メッセージ、ClientHelloおよびServerHelloは、クライアントとサーバーのセキュリティ機能を決定し、残りのハンドシェークおよびアプリケーション・データの保護に使用されるトラフィック・キーを含む共有シークレットを確立します。

ClientHello

TLSハンドシェークは、クライアントがClientHelloメッセージをサーバーに送信することから始まります。 このメッセージには次のフィールドがあります:


ノート: TLSメッセージには、ここにリストされているフィールド以外のフィールドが含まれる場合があります。TLSメッセージとそのフィールドの詳細は、TLS 1.3の指定を参照してください。


ServerHello

受け入れ可能なハンドシェーク・パラメータのセットをネゴシエートできる場合、サーバーはServerHelloメッセージでクライアントのClientHelloメッセージに応答します。 このメッセージには次のフィールドがあります:

サーバー・パラメータ

サーバーは、ServerHelloメッセージをクライアントに送信した後、EncryptedExtensionsとCertificateRequestの2つのメッセージを送信してサーバー・パラメータを確立します:

Authentication

TLSハンドシェークでサーバーとクライアントが相互に送信する最後の3つのメッセージは、Certificate、CertificateVerifyおよびFinishedです。

証明書

このメッセージには、認証証明書と、証明書チェーン内のサポートするその他の証明書が含まれます。 キー交換方法で認証に証明書を使用する場合、サーバーはこのメッセージを送信する必要があります。 サーバーがCertificateRequestメッセージを介してクライアント認証をリクエストした場合にのみ、クライアントはこれを送信する必要があります。 Certificateメッセージには、次のフィールドが含まれます:

CertificateVerify

このメッセージには、Certificateメッセージ内の公開キーに対応する秘密キーを使用したハンドシェーク全体に対する署名が含まれています。 クライアントまたはサーバーが証明書に対応する秘密キーを持っていることを証明します。 このメッセージには次のフィールドが含まれます:

Finished

このメッセージには、ハンドシェーク全体に対するMessage Authentication Code (MAC)が含まれています。 クライアントとサーバーがそれぞれのピアから受信したFinishedメッセージを検証すると、両側が接続を介してアプリケーション・データを送受信できるようになります。

事前共有キーを使用したセッション再開

事前共有キー(PSK)は、使用する前になんらかのセキュアなチャネルを使用している2者間で共有されていた共有シークレットです。 あるTLSハンドシェーク中にPSKを確立し、それを使用して別のハンドシェークで新しい接続を確立できます。これはPSKによるセッション再開と呼ばれます。 PSKは、初期ハンドシェークから導出された一意のキーに対応します。 新しい接続の確立時にサーバーがPSKを受け入れる場合、この接続のセキュリティ・コンテキストは暗号により元の接続に関連付けられ、完全なTLSハンドシェークではなく、最初のハンドシェークから導出されたキーを使用して暗号化状態がブートストラップされます。

次の図は、2つのハンドシェークを示しています。1つ目はPSKを確立し、もう1つはPSKを使用します。

PSKを確立するTLS 1.3ハンドシェイク

PSKを確立するTLS 1.3ハンドシェイク

PSKを使用するTLS 1.3ハンドシェイク

PSKを使用するTLS 1.3ハンドシェイク
  1. クライアントは、key_share拡張を含むClientHelloメッセージをサーバーに送信します。 この拡張機能は、クライアントがサポートするキー交換暗号化方式を一覧表示します。

  2. サーバーは、key_share拡張を含むServerHelloメッセージで応答します。 この拡張機能には、キー交換に使用する暗号化方式が含まれています。

  3. サーバーはそのサーバー・パラメータをクライアントに送信します。

  4. サーバーとクライアントの両方が認証メッセージを交換します。

  5. サーバーはNewSessionTicketメッセージをクライアントに送信します。このメッセージにはPSKが含まれており、クライアントはこのPSKをClientHelloメッセージのpre_shared_key拡張に含めることで、将来のハンドシェークに使用できます。

  6. クライアントとサーバーは、暗号化されたアプリケーション・データを交換できるようになりました。

  7. 将来のハンドシェークでは、クライアントは、key_shareおよびpre_shared_key拡張を含むClientHelloメッセージをサーバーに送信します。 pre_shared_key拡張には、NewTicketSessionメッセージで送信されるPSKが含まれています。

  8. サーバーは、pre_shared_keyおよびkey_share拡張を含むServerHelloメッセージで応答します。 pre_shared_key拡張には、サーバーが使用に同意したPSKが含まれます。

  9. サーバーはそのパラメータをクライアントに送信します。

  10. サーバーとクライアントは、互いにFinishedメッセージを送信します。 この接続のセキュリティ・コンテキストは暗号により元の接続に結び付けられるため、認証フェーズは実行されません。

  11. クライアントとサーバーは、暗号化されたアプリケーション・データを交換できるようになりました。


ノート: JDK 8では、次の機能はサポートされていません:


ポストハンドシェーク・メッセージ

クライアントとサーバーは、ハンドシェーク後に他のメッセージ(新規セッション・チケット・メッセージ、ポストハンドシェーク認証およびキー更新)を送信できます。

新規セッション・チケット・メッセージ

Finishedメッセージの受信後にサーバーによって送信されるNewSessionTicketメッセージには、クライアントが将来のハンドシェークに使用できる事前共有キーが含まれています。 事前共有キーを使用したセッション再開を参照してください。

ポストハンドシェーク認証

クライアントがpost_handshake_auth拡張を送信した場合、サーバーはハンドシェーク後いつでもCertificateRequestメッセージを送信してクライアント認証をリクエストできます。 クライアントが認証を受ける場合は、Certificate、CertificateVerifyおよびFinishedメッセージを送信する必要があります。 クライアントが拒否した場合は、証明書を含まないCertificateメッセージおよびFinishedメッセージを送信する必要があります。

KeyUpdateメッセージ

KeyUpdateハンドシェーク・メッセージは、送信者が送信暗号キーを更新していることを示すために使用されます。 これはTLS 1.2のChangeCipherSpecメッセージを置き換えます。

jdk.tls.keyLimitsセキュリティ・プロパティを使用して、アルゴリズムが特定のキー・セットで暗号化できるデータの量に制限を指定できます。 アルゴリズムでキー・セットを使用して暗号化可能なデータ量の制限を参照してください。

互換性のリスクと既知の問題

この項では、JSSEの機能拡張によって生じる可能性がある互換性の問題やその他の既知の問題について説明します。

TLS 1.3には以前のバージョンとの直接的な互換性がない

TLS 1.3には、以前のバージョンとの直接的な互換性がありません。 TLS 1.3を下位互換性モードで実装することは可能ですが、TLS 1.3にアップグレードする際に考慮する互換性リスクはまだいくつかあります。

TLS 1.2ハンドシェーク

SSLを使った通信は、クライアントとサーバー間の情報交換から始まります。 この情報交換をSSLハンドシェークと呼びます。 SSLハンドシェークには、次のステージがあります。

  1. 暗号化方式群のネゴシエーション

    SSLセッションは、どの暗号群を使用するかについて、クライアントとサーバーがネゴシエーションを行うことから始まります。 cipher suiteは、コンピュータがデータの暗号化に使用できる一連の暗号化アルゴリズムおよびキー・サイズです。 符号化方式には、公開キー交換アルゴリズムまたはキー合意アルゴリズム、および暗号化ハッシュ関数に関する情報が含まれます。 クライアントは利用できる暗号群をサーバーに伝え、サーバーは、どちらにも適用できる暗号群を選択します。

  2. サーバーの識別情報の認証(オプション)

    SSLの認証ステップはオプションです。しかし、Web上の電子商取引の例では、一般にクライアントがサーバーを認証します。 サーバーの認証により、サーバーが表すとクライアントが信じているエンティティを、そのサーバーが実際に表していることをクライアントが確認できます。

    サーバーは、自らが表すと唱える組織に属していることを証明するため、クライアントに公開キー証明書を提示します。 この証明書が有効であれば、クライアントはサーバーの識別情報について確信できます。

    クライアントとサーバーは、同じ秘密キーについて同意できる情報を交換します。 たとえば、RSAを使う場合、クライアントは公開キー証明書で取得したサーバーの公開キーを使用して、秘密キー情報を暗号化します。 クライアントは暗号化された秘密キー情報をサーバーに送信します。 復号化にはサーバーの非公開キーが必要なので、サーバーでだけ、このメッセージを復号化できます。

  3. 暗号化メカニズムの合意

    クライアントとサーバーは、同じ秘密キーにアクセスします。 それぞれのメッセージでは、ハンドシェークの最初のステップで選択した暗号化ハッシュ関数と、共有された秘密情報を使用して、メッセージに添付されるHMACを計算します。 次に、秘密キーと、ハンドシェークの最初のステップでネゴシエーションされた秘密キー・アルゴリズムを使用し、セキュアなデータとHMACを暗号化します。 そのあと、クライアントとサーバーは、暗号化されハッシュ化されたデータを使ってセキュアに通信することができます。

TLS 1.2プロトコル

TLS 1.2ハンドシェークでは、SSLハンドシェークについて概要を説明しました。これは、暗号化されたメッセージを送信する前にクライアントとサーバーの間で行われる情報の交換です。 詳細は、図「SSL/TLSハンドシェイク」を参照してください。 これは、SSLハンドシェークで交換される一連のメッセージを示しています。 特定の状況下でだけ送信されるメッセージには「optional」と記されています。 各SSLメッセージについては、後で詳しく説明します。

SSL/TLSハンドシェイク

この図は、SSLハンドシェークで交換される一連のメッセージを示しています。 これらのメッセージの詳細は、その後のテキストで説明します。

SSLメッセージは、次の順序で送信されます。

  1. Client hello: クライアントは、それがサポートする最上位バージョンのSSLと暗号化方式群のリスト(TLS 1.0はSSL 3.1と示される)を含むサーバー情報を送信します。 暗号化方式群の情報には、暗号化アルゴリズムとキーのサイズが含まれます。
  2. Server hello: サーバーは、クライアントとサーバーの両方がサポートする最上位バージョンのSSLと最適な暗号化方式群を選択し、この情報をクライアントに送信します。
  3. (オプション) 証明書:サーバーは、クライアントに証明書または証明書チェーンを送信します。 証明書チェーンは通常、サーバーの公開キー証明書で始まり、認証局のルート証明書で終わります。 このメッセージはオプションで、サーバー認証を求められた場合に使用します。
  4. (オプション) 証明書リクエスト:サーバーがクライアントを認証する必要がある場合は、クライアントに証明書リクエストを送信します。 インターネット・アプリケーションでは、このメッセージが使われることはほとんどありません。
  5. (オプション) サーバー・キーの交換:証明書からの公開キー情報がキー交換に十分でない場合、サーバーはクライアントにサーバー・キー交換メッセージを送信します。 たとえば、Diffie-Hellman (DH)に基づく暗号化方式群では、このメッセージにはサーバーのDH公開キーが含まれています。
  6. Server hello done: サーバーは、最初のネゴシエーション・メッセージを終了したことをクライアントに伝えます。
  7. (オプション) 証明書:クライアントからのサーバー証明書リクエストの場合、サーバーは以前と同じように証明書チェーンを送信します。

    ノート: クライアントに証明書を要求するのは、ごく一部のインターネット・サーバー・アプリケーションのみです。


  8. Client key exchange: クライアントは、対称暗号化で使用するキーを作成するために使用される情報を生成します。 RSAでは、クライアントはサーバーの公開キーでこのキー情報を暗号化してサーバーに送信します。 DHに基づく暗号化方式群の場合、このメッセージにはクライアントのDH公開キーが含まれています。
  9. (オプション) 証明書の検証:このメッセージは、前述のようにクライアントが証明書を提示したときにクライアントによって送信されます。 このメッセージは、サーバーにクライアントの認証処理を完了させるためのものです。 このメッセージが使用されると、クライアントは暗号化ハッシュ関数で電子的に署名した情報を送信します。 サーバーがクライアントの公開キーでこの情報を復号化すれば、サーバーはクライアントを認証できます。
  10. Change cipher spec: クライアントはメッセージを送信し、暗号化モードに変更するようサーバーに伝えます。
  11. Finished クライアントはサーバーに、セキュアなデータ通信を開始する準備ができたことを伝えます。
  12. Change cipher spec: サーバーはメッセージを送信し、暗号化モードを変更するようクライアントに伝えます。
  13. Finished: サーバーはクライアントに、セキュアなデータ通信を開始する準備ができたことを伝えます。 SSLハンドシェークが終了します。
  14. Encrypted data: クライアントとサーバーは、client helloとserver hello時にネゴシエーションされた対称暗号化アルゴリズムと暗号化ハッシュ関数およびclient key exchange時にクライアントがサーバーに送信した秘密キーを使用して通信します。 このときハンドシェークの再ネゴシエーションを行うことができます。 「もう一度ハンドシェイクする(再交渉)」を参照してください。
  15. メッセージを閉じる: 接続の終了時に、各側はclose_notifyアラートを送信して、接続がクローズされたことをピアに通知します。

SSLセッションで生成したパラメータを保存しておけば、将来のSSLセッションでこれらのパラメータを再利用できます。 SSLセッションのパラメータを保存しておけば、暗号化通信をすばやく開始できます。

ハンドシェークの再実行(再ネゴシエーション)

初期のハンドシェークが完了してアプリケーション・データが流れているとき、いずれの側からでも新しいハンドシェークをいつでも開始できます。 特に重要な操作について、アプリケーションで強力な暗号化方式群を使用したり、サーバー・アプリケーションでクライアント認証が必要になる場合もあります。

理由は何であれ、新しいハンドシェークが既存の暗号化セッションに置き換わり、新しいセッションが確立されるまで、アプリケーション・データとハンドシェーク・メッセージが交互に配置されます。

アプリケーションで次のいずれかのメソッドを使用して、新しいハンドシェークを開始できます。

符号化方式の選択とリモート・エンティティの検証

SSL/TLSプロトコルは、protected接続を確保するための特定の一連のステップを定義します。 ただし、暗号化方式群の選択が、接続で確保するセキュリティのタイプに直接影響します。 たとえば、匿名暗号化方式群を選択した場合、アプリケーションにはリモート・ピアの識別情報を検証する方法がありません。 暗号化しない方式群が選択された場合は、データの機密性を保護できません。 またSSL/TLSプロトコルでは、受信した資格と、ピアから送信されることが予期される資格が一致するようにとは規定していません。 接続がなんらかの理由で悪意のあるピアにリダイレクトされたときに、悪意のあるピアのクレデンシャルが現在のトラスト・データに基づいて受け付けられた場合、その接続は有効とみなされてしまいます。

raw SSLSocketおよびSSLEngineクラスを使用する場合は、データの送信前に必ずピアのクレデンシャルをチェックしてください。 SSLSocketおよびSSLEngineクラスは、URL内のホスト名がピアのクレデンシャル内のホスト名と一致することを自動的に検証しません。 ホスト名が検証されない場合、URL不正行為によってアプリケーションが悪用される可能性があります。 JDK 7以降、SSL/TLSハンドシェイク中にエンドポイントの識別/検証手順を処理できます。 SSLParameters.getEndpointIdentificationAlgorithmメソッドを参照してください。

HTTPS (HTTP Over TLS)などのプロトコルでは、ホスト名検証が必要です。 JDK 7以降、HTTPSエンドポイントの識別は、デフォルトでHttpsURLConnectionのハンドシェーク中に適用されます。 SSLParameters.getEndpointIdentificationAlgorithmメソッドを参照してください。 または、アプリケーションはHostnameVerifierインタフェースを使用して、デフォルトのHTTPSホスト名ルールをオーバーライドできます。 「HostnameVerifierインタフェース」および「HttpsURLConnectionクラス」を参照してください。


Copyright © 1993, 2025, Oracle and/or its affiliates. All rights reserved.