モジュール java.base
パッケージ javax.net.ssl

クラスSSLEngine


  • public abstract class SSLEngine
    extends Object
    Secure Sockets Layer (SSL)やIETF RFC 2246の「Transport Layer Security」(TLS)などのプロトコルを使用してセキュア通信を有効にするが、トランスポートに依存しないクラス。

    セキュア通信モードでは、次のセキュリティ保護が実施されます。

    • 整合性の保護 SSL/TLS/DTLSは、アクティブな盗聴者によるメッセージの変更から保護します。
    • 認証 ほとんどのモードで、SSL/TLS/DTLSはピア認証を提供します。 通常は、サーバー認証が行われる。サーバーからの要求に応じて、クライアント認証も行われる。
    • 機密性(プライバシの保護) ほとんどのモードで、SSL/TLS/DTLSは、クライアントとサーバーの間で送信されるデータを暗号化します。 この結果、受動的な盗聴によって、金融情報や個人情報などの機密性の高いデータが盗聴されることがない。
    これらのセキュリティ保護は、「暗号化方式群」を使用して指定します。暗号化方式群は、指定されたSSL接続で使用される暗号化アルゴリズムの組合せです。 ネゴシエーション処理中は、2つの端点に、両方の環境で使用可能である暗号化方式群が存在する必要があります。 共通の暗号化方式群がない場合は、SSL接続を確立できず、データを交換できません。

    使用される暗号化方式群は、ハンドシェークと呼ばれるネゴシエーション・プロセスによって確立されます。 ハンドシェークでは、セッションの作成またはセッションへの参加が行われます。このセッションは、時間の経過とともにさまざまな接続を保護します。 ハンドシェークが完了すると、getSession()メソッドを使用してセッション属性にアクセスできます。

    SSLSocketクラスもほぼ同じセキュリティ機能を提供しますが、すべての着信および発信データは、意図的にブロック・モデルを使用する配下のSocketにより自動的に送信されます。 この処理は多くのアプリケーションに対して適切ですが、このモデルは大規模サーバーに必要な拡張性をもたらしません。

    SSLEngineの主な特長として、転送メカニズムに依存することなくインバウンド/アウトバウンドのバイト・ストリームに作用する点があげられます。 SSLEngineユーザーは、ピアに対する入出力転送の信頼性を確保する必要があります。 SSLEngineは、I/O転送メカニズムからSSL/TLS/DTLS抽象を分離することにより、non-blocking I/O (polling)selectable non-blocking I/OSocket、従来のInput/OutputStreams、ローカルByteBuffersまたはバイト配列、「将来の非同期I/Oモデル」などのさまざまなI/O型に使用できます。等々。

    高レベルでは、SSLEngineは次のように表されます。

                       app data
    
                    |           ^
                    |     |     |
                    v     |     |
               +----+-----|-----+----+
               |          |          |
               |       SSL|Engine    |
       wrap()  |          |          |  unwrap()
               | OUTBOUND | INBOUND  |
               |          |          |
               +----+-----|-----+----+
                    |     |     ^
                    |     |     |
                    v           |
    
                       net data
     
    アプリケーション・データ(別名「プレーン・テキスト」または「クリアテキスト」)は、アプリケーションによって生成または使用されるデータです。 アプリケーション・データと対になるものとして、ネットワーク・データがあります。ネットワーク・データは、ハンドシェークまたは暗号文(暗号化された)、またはその両方のいずれかで構成され、入出力メカニズムを介して転送されるデータです。 インバウンド・データはピアから受信されるデータ、アウトバウンド・データはピアへ送信されるデータです。

    SSLEngineのコンテキストでは、セキュア接続の確立および制御目的で交換されるデータをハンドシェーク・データと総称します。 ハンドシェイク・データには、SSL/TLS/DTLSメッセージ"alert"、"change_cipher_spec,"、および"握手。"が含まれます)

    SSLEngineは、次の5つの段階をたどります。

    1. 作成 - SSLEngineの作成と初期化は完了しましたが、まだ使用されてはいません。 この段階では、アプリケーションにより、SSLEngine固有のあらゆる設定(暗号化方式群の有効化、SSLEngineがクライアント・モードとサーバー・モードのどちらでハンドシェークを行うかなど)を行うことができます。 ハンドシェークが始まると、次のハンドシェークからクライアント/サーバー・モードの設定を除く(下記参照)新しい設定が使用されます。
    2. 初期ハンドシェーク - SSLSessionが確立されるまでの間、2つのピアが通信パラメータを交換する手続きです。 この段階では、アプリケーション・データは送信できません。
    3. アプリケーション・データ - 通信パラメータが確立され、ハンドシェークが完了すると、SSLEngineからアプリケーション・データが送信されます。 アウトバウンド・アプリケーション・メッセージは暗号化され、データの整合性が確保されます。インバウンド・メッセージでは、この逆の手続きが行われます。
    4. 再ハンドシェーク -アプリケーション・データ段階の間はいつでも、どちら側のピアからでも、必要に応じてセッションの再ネゴシエーションを要求できます。 アプリケーション・データに新しいハンドシェーク・データを混合できます。 再ハンドシェーク・フェーズを開始する前に、アプリケーションは、有効な暗号スイートのリストやクライアント認証を使用するかどうかなどのSSL/TLS/DTLS通信パラメータをリセットすることができますが、クライアント/サーバー・モード間で変更することはできません。 前回と同様に、ハンドシェークが始まってから次のハンドシェークまで、新しいSSLEngine構成設定は使用されません。
    5. 終了 - 接続が不要になったとき、アプリケーションは、SSLEngineを終了し、ピアと送受信するメッセージが残っている場合は送受信を完了してから、配下の転送メカニズムを終了する必要があります。 いったん閉じられたエンジンを再利用することはできません。新しいSSLEngineを作成する必要があります。
    SSLEngineを作成するには、初期化されたSSLContextからSSLContext.createSSLEngine()を呼び出します。 wrap()unwrap()、またはbeginHandshake()を最初に呼び出す前に、任意の構成パラメータを構成してください。 これらのメソッドはすべて、初期ハンドシェークをトリガーします。

    エンジン内でデータを移動するには、アウトバウンド・データの場合はwrap()、インバウンド・データの場合はunwrap()をそれぞれ呼び出します。 SSLEngineの状態によっては、wrap()呼出しによってソース・バッファからアプリケーション・データが消費され、宛先バッファにネットワーク・データが生成される場合もあります。 アウトバウンド・データには、アプリケーション・データまたはハンドシェーク・データ、あるいはその両方が含まれます。 unwrap()を呼び出すと、ソース・バッファがチェックされ、データがハンドシェーク情報であればハンドシェークが実施されます。アプリケーションであれば、アプリケーション・データが宛先バッファに格納されます。 基礎となるSSL/TLS/DTLSアルゴリズムの状態によって、データが消費されて生成される時期が決まります。

    wrap()unwrap()を呼び出すと、オペレーションの状態と、処理を続行する場合のエンジンとのやりとりの内容(オプション)を示すSSLEngineResultが返されます。

    SSLEngineは、完全なSSL/TLS/DTLSパケットのみを生成/消費し、wrap()/unwrap()への呼び出しの間に内部的にアプリケーション・データを格納しません。 したがって、生成されるレコードのうち最大のものを格納できるように、入出力ByteBufferのサイズを決定する必要があります。 適切なバッファ・サイズを決定するには、SSLSession.getPacketBufferSize()SSLSession.getApplicationBufferSize()の呼び出しを使用する必要があります。 アウトバウンド・アプリケーション・データのバッファ・サイズは、通常、考慮する必要はありません。 データの使用および生成に適したバッファ条件でない場合、アプリケーションはSSLEngineResultによって問題を特定し、修正したあと、再度呼出しを試行しなければいけません。

    たとえば、有効な宛先バッファの容量が不十分であるとエンジンが判定した場合、unwrap()SSLEngineResult.Status.BUFFER_OVERFLOWの結果を返します。 必要に応じて、アプリケーションでSSLSession.getApplicationBufferSize()を呼び出し、その値と宛先バッファ内の有効な容量を比較して、バッファを大きくするようにしてください。 同様に、unwrap()SSLEngineResult.Status.BUFFER_UNDERFLOWを返そうとした場合は、アプリケーションでSSLSession.getPacketBufferSize()を呼び出して、レコードを保持するのに十分な容量をソース・バッファに確保し(また、必要に応じて拡張し)、より多くの着信データを取得するようにしてください。

    
       SSLEngineResult r = engine.unwrap(src, dst);
       switch (r.getStatus()) {
       BUFFER_OVERFLOW:
           // Could attempt to drain the dst buffer of any already obtained
           // data, but we'll just increase it to the size needed.
           int appSize = engine.getSession().getApplicationBufferSize();
           ByteBuffer b = ByteBuffer.allocate(appSize + dst.position());
           dst.flip();
           b.put(dst);
           dst = b;
           // retry the operation.
           break;
       BUFFER_UNDERFLOW:
           int netSize = engine.getSession().getPacketBufferSize();
           // Resize buffer if needed.
           if (netSize > dst.capacity()) {
               ByteBuffer b = ByteBuffer.allocate(netSize);
               src.flip();
               b.put(src);
               src = b;
           }
           // Obtain more inbound network data for src,
           // then retry the operation.
           break;
       // other cases: CLOSED, OK.
       }
     

    SSLSocketとは異なり、SSLEngineのメソッドはすべて非ブロックになります。 SSLEngine実装は、完了までに長い時間がかかったり、ブロックしてしまう可能性のあるタスクの結果を必要とする可能性があります。 たとえば、TrustManagerでは、リモート証明書検証サービスへの接続が必要になる場合があります。また、KeyManagerは、クライアント認証の一環として使用する証明書を決定するようにユーザーに要求する必要がある場合があります。 さらに、暗号化署名を作成し、これらを検証する場合、処理時間がかなり長くなり、処理がブロックされたように見えることがあります。

    SSLEngineは、ブロックされる可能性があるあらゆるオペレーションに対して、Runnable委譲タスクを生成します。 SSLEngineResultにより、委譲タスクの結果の必要性が示された場合、アプリケーションはgetDelegatedTask()を呼び出して未処理の委譲タスクを取得し、そのrun()メソッドを呼び出す必要があります。呼出しに使用されるスレッドは、計算方法によって異なります。 アプリケーションは、すべての委譲タスクを取得すると、元の操作を再試行します。

    通信セッションの終了時に、アプリケーションはSSL/TLS/DTLSリンクを適切に閉じる必要があります。 SSL/TLS/DTLSプロトコルにはクロージャ・ハンドシェイク・メッセージがあり、これらのメッセージは、SSLEngineを解放して基礎となるトランスポート・メカニズムを閉じる前に、ピアに通信する必要があります。 通信セッションの終了は、SSLException、ハンドシェーク終了メッセージの着信、または任意の終了メソッドによって開始されます。 どの場合でも、エンジンからハンドシェーク終了メッセージが生成され、SSLEngineResultの状態がCLOSEDになるか、isOutboundDone()の戻り値がtrueになるまで、wrap()が繰返し呼び出されます。 wrap()メソッドによって取得されたデータはすべてピアに送信されます。

    アプリケーションから送信されるデータがもうないことをエンジンに通知するには、closeOutbound()を使用します。

    ピアは、固有のハンドシェーク終了メッセージを送信することで、終了の意図を通知します。 このメッセージがローカルのSSLEngineunwrap()呼出しによって受信および処理されると、アプリケーションは、unwrap()を呼び出し、ステータスがCLOSEDのSSLEngineResultを検索します。条件に合うものが見つかるか、isInboundDone()の戻り値がtrueであれば、終了が確認されます。 何らかの理由で、ピアが適切なSSL/TLS/DTLSクロージャ・メッセージを送信せずに通信リンクを閉じると、アプリケーションはストリームの終わりを検出してcloseInbound()を介して処理するインバウンド・メッセージがなくなることをエンジンに知らせることができます。 アプリケーションによっては、ピアからのシャットダウン・メッセージを順序どおりに受け取るように要求する設定になっている場合があります。このような場合、アプリケーションはストリームの終了位置の条件ではなく、ハンドシェーク・メッセージによって終了をチェックできます。

    暗号化方式群を使用するときは、2つのグループについて理解する必要があります。

    • サポートされる暗号化方式群: SSL実装でサポートされるすべての暗号化方式群。 このリストは、getSupportedCipherSuites()を使用して報告される。
    • 有効になっている暗号化方式群。サポートされる暗号化方式群の完全なセットより少ないことがある。 このグループは、setEnabledCipherSuites(String [])メソッドを使用して設定し、getEnabledCipherSuites()メソッドを使用して照会する。 新しいエンジンでは、最小限の推奨構成を表すデフォルトの暗号化方式群が使用可能になっている。
    デフォルトの実装で使用可能にする暗号化方式群では、サーバーを認証し、機密性が保証されなければいけません。 サーバー認証が行われず機密性が保証されない暗号化方式群を選択する場合は、サーバー認証が行われず非公開性が保証されない(暗号化されない)通信が使用されることに2つの終端が明示的に同意する必要があります。

    各SSL/TLS/DTLS接続には1つのクライアントと1つのサーバーが必要です。したがって、各エンドポイントはどのロールを担うかを決定する必要があります。 この選択内容によって、どちら側からハンドシェーク処理を開始するか、また、お互いにどのタイプのメッセージを送信するかが決まります。 setUseClientMode(boolean)メソッドはモードを構成します。 いったん初期ハンドシェークが開始されてからは、再ネゴシエーションを実行する場合でも、SSLEngineのモードをクライアントからサーバー、サーバーからクライアントに切り替えることはできません。

    アプリケーションにより、委譲タスクを別スレッドで処理するように選択できます。 SSLEngineが作成されると、現在のAccessControlContextが保存されます。 その後、すべての委譲タスクはこのコンテキストで処理されます。つまり、アクセス制御の意思決定はすべて、エンジンの作成時のに前方参照されたコンテキストを使用してなされます。


    並行処理について: 次の2点に注意してください。
    1. wrap()メソッドとunwrap()メソッドは、並行実行が可能です。
    2. SSL/TLS/DTLSプロトコルは順序付きパケットを使用します。 アプリケーションは、生成されたパケットが正しい順番で配信する必要があります。 パケットの到着順序が正しくないと、予期しない結果または致命的な結果を招くことがあります。

      例を示します。

                    synchronized (outboundLock) {
                        sslEngine.wrap(src, dst);
                        outboundQueue.put(dst);
                    }
            
      最終的なパケットの順序を保証することができないので、結果的に、2つのスレッドが同じメソッド(wrap()またはunwrap())を並行して呼び出すことはできません。
    導入されたバージョン:
    1.5
    関連項目:
    SSLContext, SSLSocket, SSLServerSocket, SSLSession, Socket
    • コンストラクタのサマリー

      コンストラクタ 
      修飾子 コンストラクタ 説明
      protected SSLEngine()
      内部セッションの再利用方法に関するヒントを提供しないSSLEngineのコンストラクタ。
      protected SSLEngine​(String peerHost, int peerPort)
      SSLEngineのコンストラクタ。
    • コンストラクタの詳細

      • SSLEngine

        protected SSLEngine​(String peerHost,
                            int peerPort)
        SSLEngineのコンストラクタ。

        SSLEngine実装は、内部セッションを再利用するためのヒントとして、peerHostパラメータとpeerPortパラメータを使用できます。

        Kerberosなど、リモート・ホスト名の情報を必要とする暗号化方式群もあります。 このクラスの実装は、このコンストラクタを使ってKerberosを使用します。

        パラメータは、SSLEngineによる認証を受けません。

        パラメータ:
        peerHost - ピアのホスト名
        peerPort - ピアのポート番号
        関連項目:
        SSLContext.createSSLEngine(String, int), SSLSessionContext
    • メソッドの詳細

      • getPeerHost

        public String getPeerHost()
        ピアのホスト名を返します。

        この値は認証されていないため、実際に使用することはできません。

        戻り値:
        ピアのホスト名。使用できるものがない場合はnull。
      • getPeerPort

        public int getPeerPort()
        ピアのポート番号を返します。

        この値は認証されていないため、実際に使用することはできません。

        戻り値:
        ピアのポート番号。使用できるものがない場合は -1。
      • wrap

        public SSLEngineResult wrap​(ByteBuffer src,
                                    ByteBuffer dst)
                             throws SSLException
        平文アプリケーション・データのバッファをSSL/TLS/DTLSネットワーク・データにエンコードしようとします。

        このメソッド呼出しの動作は、次の呼出しの動作とまったく同じです。

         engine.wrap(new ByteBuffer [] { src }, 0, 1, dst);
         
        パラメータ:
        src - アウトバウンド・アプリケーション・データを格納するByteBuffer
        dst - 送信ネットワーク・データを保持するByteBuffer
        戻り値:
        このオペレーションの結果を説明するSSLEngineResult
        例外:
        SSLException - データの処理中に問題が検出され、それがSSLEngineの異常終了の原因になった場合。 エンジンの終了の詳細は、クラスの説明を参照。
        ReadOnlyBufferException - dstバッファが読取り専用である場合。
        IllegalArgumentException - srcまたはdstのいずれかがnullの場合。
        IllegalStateException - クライアント/サーバー・モードがまだ設定されていない場合。
        関連項目:
        wrap(ByteBuffer [], int, int, ByteBuffer)
      • wrap

        public SSLEngineResult wrap​(ByteBuffer[] srcs,
                                    ByteBuffer dst)
                             throws SSLException
        プレーンテキスト・バイトを一連のデータ・バッファからSSL/TLS/DTLSネットワーク・データにエンコードしようとします。

        このメソッド呼出しの動作は、次の呼出しの動作とまったく同じです。

         engine.wrap(srcs, 0, srcs.length, dst);
         
        パラメータ:
        srcs - 送信アプリケーション・データを含むByteBuffersの配列
        dst - 送信ネットワーク・データを保持するByteBuffer
        戻り値:
        このオペレーションの結果を説明するSSLEngineResult
        例外:
        SSLException - データの処理中に問題が検出され、それがSSLEngineの異常終了の原因になった場合。 エンジンの終了の詳細は、クラスの説明を参照。
        ReadOnlyBufferException - dstバッファが読取り専用である場合。
        IllegalArgumentException - srcsdstのどちらかがnullの場合、またはsrcs内のいずれかの要素がnullである場合。
        IllegalStateException - クライアント/サーバー・モードがまだ設定されていない場合。
        関連項目:
        wrap(ByteBuffer [], int, int, ByteBuffer)
      • wrap

        public abstract SSLEngineResult wrap​(ByteBuffer[] srcs,
                                             int offset,
                                             int length,
                                             ByteBuffer dst)
                                      throws SSLException
        データ・バッファのサブ・シーケンスから平文バイトをSSL/TLS/DTLSネットワーク・データにエンコードしようとします。 この収集オペレーションは、1回の呼出しで、単一のバイト・シーケンスを1つ以上の指定のバッファ・シーケンスへエンコードできます。 ラップ収集は、通常、ネットワーク・プロトコルやファイル形式(たとえば、データを1個以上の固定長のヘッダーと可変長の本体から成るセグメントにグループ化するようなファイル形式)を実装する際に便利です。 収集の詳細はGatheringByteChannel、収集後の動作の詳細はGatheringByteChannel.write(ByteBuffer[], int, int)を参照してください。

        SSLEngineの状態によっては、このメソッドは、アプリケーション・データを一切使用しないでネットワーク・データを生成することがあります。たとえば、ハンドシェーク・データがこれに該当します。

        アプリケーションは、ネットワーク・データをピアに安全に転送する必要があります。また、何回かのwrap()の呼出しによって生成されたデータを生成順に転送する必要があります。 アプリケーションは、このメソッドの複数の呼出しを正しく同期化する必要があります。

        このSSLEngineがまだ初期ハンドシェークを開始していない場合は、このメソッドによって初期ハンドシェークが自動的に開始されます。

        このメソッドはSSL/TLS/DTLSレコードを生成しようとしますが、できるだけ多くのソース・データを消費しますが、各バッファに残っているバイトの合計以上を消費することはありません。 ByteBufferの位置は、消費または生成されたデータの量を反映するように更新されます。 上限/下限値は変わりません。

        srcsおよびdst ByteBufferは、配下にあるそれぞれ別々のメモリーを使用する必要があります。

        エンジンの終了の詳細は、クラスの説明を参照。

        パラメータ:
        srcs - 送信アプリケーション・データを含むByteBuffersの配列
        offset - バイトの取得元となる最初のバッファ配列内のオフセット。srcs.length以下の負でない値である必要があります
        length - アクセスされる最大バッファ数。srcs.length - offset以下の負でない値である必要があります
        dst - 送信ネットワーク・データを保持するByteBuffer
        戻り値:
        このオペレーションの結果を説明するSSLEngineResult
        例外:
        SSLException - データの処理中に問題が検出され、それがSSLEngineの異常終了の原因になった場合。 エンジンの終了の詳細は、クラスの説明を参照。
        IndexOutOfBoundsException - offsetパラメータとlengthパラメータの前提条件が満たされていない場合。
        ReadOnlyBufferException - dstバッファが読取り専用である場合。
        IllegalArgumentException - srcsdstのどちらかがnullの場合、または指定されたsrcsサブシーケンス内のいずれかの要素がnullである場合。
        IllegalStateException - クライアント/サーバー・モードがまだ設定されていない場合。
        関連項目:
        GatheringByteChannel, GatheringByteChannel.write( ByteBuffer[], int, int)
      • unwrap

        public SSLEngineResult unwrap​(ByteBuffer src,
                                      ByteBuffer dst)
                               throws SSLException
        SSL/TLS/DTLSネットワーク・データを平文アプリケーション・データ・バッファにデコードしようとします。

        このメソッド呼出しの動作は、次の呼出しの動作とまったく同じです。

         engine.unwrap(src, new ByteBuffer [] { dst }, 0, 1);
         
        パラメータ:
        src - 着信ネットワーク・データを含むByteBuffer
        dst - インバウンド・アプリケーション・データを格納するByteBuffer
        戻り値:
        このオペレーションの結果を説明するSSLEngineResult
        例外:
        SSLException - データの処理中に問題が検出され、それがSSLEngineの異常終了の原因になった場合。 エンジンの終了の詳細は、クラスの説明を参照。
        ReadOnlyBufferException - dstバッファが読取り専用である場合。
        IllegalArgumentException - srcまたはdstのいずれかがnullの場合。
        IllegalStateException - クライアント/サーバー・モードがまだ設定されていない場合。
        関連項目:
        unwrap(ByteBuffer, ByteBuffer [], int, int)
      • unwrap

        public SSLEngineResult unwrap​(ByteBuffer src,
                                      ByteBuffer[] dsts)
                               throws SSLException
        SSL/TLS/DTLSネットワーク・データを一連の平文アプリケーション・データ・バッファにデコードしようとします。

        このメソッド呼出しの動作は、次の呼出しの動作とまったく同じです。

         engine.unwrap(src, dsts, 0, dsts.length);
         
        パラメータ:
        src - 着信ネットワーク・データを含むByteBuffer
        dsts - 着信アプリケーション・データを保持するByteBufferの配列。
        戻り値:
        このオペレーションの結果を説明するSSLEngineResult
        例外:
        SSLException - データの処理中に問題が検出され、それがSSLEngineの異常終了の原因になった場合。 エンジンの終了の詳細は、クラスの説明を参照。
        ReadOnlyBufferException - いずれかのdstバッファが読取り専用の場合。
        IllegalArgumentException - srcdstsのどちらかがnullの場合、またはdsts内のいずれかの要素がnullである場合。
        IllegalStateException - クライアント/サーバー・モードがまだ設定されていない場合。
        関連項目:
        unwrap(ByteBuffer, ByteBuffer [], int, int)
      • unwrap

        public abstract SSLEngineResult unwrap​(ByteBuffer src,
                                               ByteBuffer[] dsts,
                                               int offset,
                                               int length)
                                        throws SSLException
        SSL/TLS/DTLSネットワーク・データをplaintextアプリケーション・データ・バッファのサブ・シーケンスにデコードしようとします。 この散布オペレーションは、1回の呼出しで、単一のバイト・シーケンスを1つ以上の指定のバッファ・シーケンスへデコードできます。 分散するアンラップは、通常、ネットワーク・プロトコルやファイル形式(たとえば、データを1個以上の固定長のヘッダーと可変長の本体から成るセグメントにグループ化するようなファイル形式)を実装する際に便利です。 散布の詳細はScatteringByteChannel、散布後の動作の詳細はScatteringByteChannel.read(ByteBuffer[], int, int)を参照してください。

        SSLEngineの状態によっては、このメソッドは、アプリケーション・データを一切生成しないでネットワーク・データを使用することがあります。たとえば、ハンドシェーク・データがこれに該当します。

        アプリケーションは、ピアからネットワーク・データを安全に取得する必要があります。また、受信した順にデータのラップを解除(unwrap()呼び出し)する必要があります。 アプリケーションは、このメソッドの複数の呼出しを正しく同期化する必要があります。

        このSSLEngineがまだ初期ハンドシェークを開始していない場合は、このメソッドによって初期ハンドシェークが自動的に開始されます。

        このメソッドは、1つの完全なSSL/TLS/DTLSネットワーク・パケットを消費しようとしますが、バッファに残っているバイトの合計以上を消費することはありません。 ByteBufferの位置は、消費または生成されたデータの量を反映するように更新されます。 上限/下限値は変わりません。

        srcおよびdsts ByteBufferは、配下にあるそれぞれ別々のメモリーを使用する必要があります。

        この呼出しの結果、インバウンドのネットワーク・バッファが変更されることがあります。このため、二次的な目的でネットワーク・データ・パケットが必要な場合は、このメソッドの呼出しの前にデータを複製する必要があります。 ノート: 各SSLEngineにはSSL/TLS/DTLSメッセージに影響を与えるユニークなランダムな状態が含まれているため、ネットワーク・データは2番目のSSLEngineには役立ちません。

        エンジンの終了の詳細は、クラスの説明を参照。

        パラメータ:
        src - 着信ネットワーク・データを含むByteBuffer
        dsts - 着信アプリケーション・データを保持するByteBufferの配列。
        offset - 最初のバイトの転送先となるバッファ配列内のオフセット。dsts.length以下のゼロまたは正の数。
        length - アクセスされる最大バッファ数。dsts.length - offset以下の負でない値である必要があります。
        戻り値:
        このオペレーションの結果を説明するSSLEngineResult
        例外:
        SSLException - データの処理中に問題が検出され、それがSSLEngineの異常終了の原因になった場合。 エンジンの終了の詳細は、クラスの説明を参照。
        IndexOutOfBoundsException - offsetパラメータとlengthパラメータの前提条件が満たされていない場合。
        ReadOnlyBufferException - いずれかのdstバッファが読取り専用の場合。
        IllegalArgumentException - srcdstsのどちらかがnullの場合、または指定されたdstsサブシーケンス内のいずれかの要素がnullである場合。
        IllegalStateException - クライアント/サーバー・モードがまだ設定されていない場合。
        関連項目:
        ScatteringByteChannel, ScatteringByteChannel.read( ByteBuffer[], int, int)
      • getDelegatedTask

        public abstract Runnable getDelegatedTask()
        このSSLEngineに委譲されたRunnableタスクを返します。

        SSLEngineオペレーションに必要なオペレーションの結果がブロックされたり、完了までにかなりの時間がかかることがあります。 このメソッドは、未処理のRunnableオペレーション(タスク)を取得するために使用されます。 各タスクには、runオペレーションを実行するスレッド(現在のスレッドも可)を割り当てる必要があります。 runメソッドが終了したあと、不要になったRunnableオブジェクトは廃棄可能です。

        委譲されたタスクは、AccessControlContext内で、このオブジェクトが作成されたときに実行されます。

        このメソッドの呼出しは、未処理のタスクをそれぞれ1回だけ返します。

        委譲された複数のタスクを並列実行することもできます。

        戻り値:
        委譲されたRunnableタスク。使用できるものがない場合はnull。
      • closeInbound

        public abstract void closeInbound()
                                   throws SSLException
        このSSLEngineにこれ以上の着信ネットワーク・データが送信されないことを示す信号。

        アプリケーションがcloseOutbound()を呼び出して終了処理を開始したとき、ピアの対応する終了メッセージを待つ必要がない場合があります。 (終了の警告の待機に関する詳細は、TLS仕様のセクション7.2.1(RFC 2246)を参照)。 この場合、このメソッドの呼出しは不要です。

        しかし、アプリケーションがクロージャ・プロセスを開始しなかった場合、または上記の状況が適用されない場合は、SSL/TLS/DTLSデータ・ストリームの終わりに達するたびにこのメソッドを呼び出す必要があります。 これにより、インバウンド側のクロージャが確実に行われ、ピアがSSL/TLS/DTLSクローズ手順に正しく従っているかどうかがチェックされ、切り捨て攻撃が検出されます。

        このメソッドは、べき等です。着信側がすでに終了している場合は、何も行いません。

        残りのハンドシェーク・データをフラッシュするには、wrap()を呼び出すようにしてください。

        例外:
        SSLException - このエンジンがピアから適切なSSL/TLS/DTLS close通知メッセージを受信していない場合。
        関連項目:
        isInboundDone(), isOutboundDone()
      • isInboundDone

        public abstract boolean isInboundDone()
        unwrap(ByteBuffer, ByteBuffer)がこれ以上の着信データ・メッセージを受け入れるかどうかを返します。
        戻り値:
        SSLEngineがこれ以上ネットワーク・データを使用しない場合(言い換えれば、これ以上アプリケーション・データを生成しない場合)はtrue。
        関連項目:
        closeInbound()
      • closeOutbound

        public abstract void closeOutbound()
        このSSLEngineでこれ以上の送信アプリケーション・データが送信されないことを示す信号。

        このメソッドは、べき等です。送信側がすでに終了している場合は、何も行いません。

        残りのハンドシェーク・データをフラッシュするには、wrap(ByteBuffer, ByteBuffer)を呼び出すようにしてください。

        関連項目:
        isOutboundDone()
      • isOutboundDone

        public abstract boolean isOutboundDone()
        wrap(ByteBuffer, ByteBuffer)がこれ以上の送信データ・メッセージを生成するかどうかを返します。

        終了段階で、SSLEngineは、ピアに送信するハンドシェーク終了データを生成します。このデータを生成するには、wrap()を呼び出す必要があります。 このメソッドの戻り値がtrueの場合、これ以上アウトバウンド・データは生成されません。

        戻り値:
        SSLEngineがこれ以上ネットワーク・データを生成しない場合はtrue
        関連項目:
        closeOutbound(), closeInbound()
      • getSupportedCipherSuites

        public abstract String[] getSupportedCipherSuites()
        このエンジンで使用可能にできる暗号化方式群の名前を返します。 通常は、その一部のみがデフォルトで使用可能になります。デフォルトのサービス品質要件を満たしていない暗号化方式群は、使用不可になります。 これらの暗号化方式群は、特殊なアプリケーションで使用されます。

        返される配列には、Java Cryptography Architecture標準アルゴリズム名ドキュメントの「JSSE暗号スイート名」セクションの標準暗号スイート名のリストからの暗号スイートが含まれ、プロバイダがサポートする他の暗号スイートも含まれます。

        戻り値:
        暗号化方式群名の配列
        関連項目:
        getEnabledCipherSuites(), setEnabledCipherSuites(String [])
      • getEnabledCipherSuites

        public abstract String[] getEnabledCipherSuites()
        このエンジンで現在使用可能になっているSSL暗号化方式群の名前を返します。 SSLエンジンが最初に作成されたときに、使用可能になっているすべての暗号化方式群で、最小限のサービス品質が保証されます。 環境によっては、この値は空の場合もあります。

        スイートが有効になっている場合でも、スイートは使用できないことに注意してください。 これは、ピアがサポートしていないか、またはその使用が制限されているか、スイートの必須の証明書(秘密鍵)が利用できない場合、または匿名スイートが有効であるが認証が必要な場合に発生します。

        返される配列には、Java Cryptography Architecture標準アルゴリズム名ドキュメントの「JSSE暗号スイート名」セクションの標準暗号スイート名のリストからの暗号スイートが含まれ、プロバイダがサポートする他の暗号スイートも含まれます。

        戻り値:
        暗号化方式群名の配列
        関連項目:
        getSupportedCipherSuites(), setEnabledCipherSuites(String [])
      • setEnabledCipherSuites

        public abstract void setEnabledCipherSuites​(String[] suites)
        このエンジンで使用可能な暗号化方式群を設定します。

        suitesパラメータ内の各暗号化方式群はgetSupportedCipherSuites()でリストされている必要があります。そうでない場合、このメソッドは失敗します。 このメソッドの呼出しが成功したあと、suitesパラメータに示されている暗号化方式群のみが使用可能になります。

        暗号スイート名の標準リストは、Java暗号化アーキテクチャの標準アルゴリズム名のドキュメントの「JSSE暗号スイート名」セクションにあります。 プロバイダは、このリストにない暗号スイート名をサポートしているか、特定の暗号スイートの推奨名を使用していない可能性があります。

        なぜ特定の暗号化方式群をエンジンで使用することができないかについては、getEnabledCipherSuites()を参照してください。

        パラメータ:
        suites - 有効にするすべての暗号化方式群の名前
        例外:
        IllegalArgumentException - パラメータで指定された暗号化方式群の1つ以上がサポートされていないか、またはパラメータがnullである場合。
        関連項目:
        getSupportedCipherSuites(), getEnabledCipherSuites()
      • getSupportedProtocols

        public abstract String[] getSupportedProtocols()
        このSSLEngineで使用可能にできるプロトコルの名前を返します。
        戻り値:
        サポートされているプロトコルの配列
      • getEnabledProtocols

        public abstract String[] getEnabledProtocols()
        このSSLEngineで現在使用可能になっているプロトコル・バージョンの名前を返します。

        プロトコルが有効になっていても、決して使用されないことに注意してください。 これは、ピアがプロトコルをサポートしていないか、またはその使用が制限されているか、プロトコルによってサポートされている有効な暗号スイートがない場合に発生します。

        戻り値:
        プロトコルの配列
        関連項目:
        setEnabledProtocols(String [])
      • setEnabledProtocols

        public abstract void setEnabledProtocols​(String[] protocols)
        このエンジンで使用可能なプロトコルのバージョンを設定します。

        プロトコルは、getSupportedProtocols()により、サポート対象としてリストされていなければいけません。 このメソッドの呼出しが成功したあと、protocolsパラメータに示されているプロトコルのみが使用可能になります。

        パラメータ:
        protocols - 有効にするすべてのプロトコルの名前。
        例外:
        IllegalArgumentException - パラメータで指定されたプロトコルの1つ以上がサポートされていないか、またはprotocolsパラメータがnullである場合。
        関連項目:
        getEnabledProtocols()
      • getSession

        public abstract SSLSession getSession()
        このSSLEngineで使用されているSSLSessionを返します。

        これらは有効期間が長く、ユーザーによってはログイン・セッション全体に対応することもあります。 セッションには、セッション内のすべての接続で使用される暗号化方式群と、セッションのクライアントとサーバーの識別情報が指定されています。

        このメソッドは、SSLSocket.getSession()とは異なり、ハンドシェークが完了するまでブロックされません。

        初期ハンドシェークが完了すると、無効な暗号化方式群SSL_NULL_WITH_NULL_NULLを報告するセッション・オブジェクトを返します。

        戻り値:
        このSSLEngineSSLSession
        関連項目:
        SSLSession
      • getHandshakeSession

        public SSLSession getHandshakeSession()
        SSL/TLS/DTLSハンドシェイク中に構築されているSSLSessionを返します。

        TLS/DTLSプロトコルは、このクラスのインスタンスを使用する際に、SSLSessionが完全に初期化され、getSessionで利用可能になる前に、必要なパラメータをネゴシエートできます。 たとえば、有効なシグネチャ・アルゴリズムのリストによって、TrustManagerの決定時に使用できる証明書のタイプが制限されたり、TLS/DTLSフラグメントの最大パケット・サイズがネットワーク環境をよりよくサポートできるようにサイズを変更することができます。

        このメソッドでは、構築されているSSLSessionに早期にアクセスできます。 ハンドシェークの進捗状況によっては、一部のデータがまだ使用できない可能性があります。 たとえば、リモート・サーバーが証明書チェーンを送信しようとしているが、そのチェーンがまだ処理されていない場合、SSLSessiongetPeerCertificatesメソッドはSSLPeerUnverifiedExceptionをスローします。 そのチェーンの処理が完了すると、getPeerCertificatesは適切な値を返します。

        戻り値:
        このインスタンスが現在ハンドシェークしていない場合、または現在のハンドシェークが基本的なSSLSessionを作成できる程十分に進捗していない場合はnull。 それ以外の場合、このメソッドは、現在ネゴシエーションが行われているSSLSessionを返します。
        例外:
        UnsupportedOperationException - ベースとなるプロバイダがこの操作を実装していない場合。
        導入されたバージョン:
        1.7
        関連項目:
        SSLSocket, SSLSession, ExtendedSSLSession, X509ExtendedKeyManager, X509ExtendedTrustManager
      • beginHandshake

        public abstract void beginHandshake()
                                     throws SSLException
        このSSLEngineの初期ハンドシェークまたは再ネゴシエーションのハンドシェークを開始します。

        このメソッドは、初期ハンドシェーク時には必要ありません。ハンドシェークがまだ開始されていない場合は、wrap()メソッドとunwrap()メソッドによって暗黙的にこのメソッドが呼び出されるからです。

        ピアも、適切なセッション再ネゴシエーションのハンドシェーク・メッセージを送信することにより、このSSLEngineとのセッションの再ネゴシエーションを要求することがあります。

        このメソッドは、SSLSocket#startHandshake()メソッドとは異なり、ハンドシェークが完了するまでブロックされません。

        SSL/TLS/DTLSセッションの再ネゴシエーションを完全に強制するには、このメソッドを呼び出す前に現在のセッションを無効にする必要があります。

        既存のエンジン上で複数のハンドシェークをサポートせず、SSLExceptionをスローするプロトコルもあります。

        例外:
        SSLException - SSLEngineに新しくハンドシェークを開始するように通知しているとき、問題が発生した場合。 エンジンの終了の詳細は、クラスの説明を参照。
        IllegalStateException - クライアント/サーバー・モードがまだ設定されていない場合。
        関連項目:
        SSLSession.invalidate()
      • getHandshakeStatus

        public abstract SSLEngineResult.HandshakeStatus getHandshakeStatus()
        このSSLEngineの現在のハンドシェーク状態を返します。
        戻り値:
        現在のSSLEngineResult.HandshakeStatus
      • setUseClientMode

        public abstract void setUseClientMode​(boolean mode)
        ハンドシェーク時、エンジンがクライアント(またはサーバー)モードを使用するように構成します。

        このメソッドは、すべてのハンドシェークの前に呼び出す必要があります。 いったんハンドシェークが開始されると、このエンジンの寿命が尽きるまで、現在のモードをリセットすることはできません。

        通常、サーバーは自身を認証しますが、クライアントは必ずしもそうとはかぎりません。

        パラメータ:
        mode - ハンドシェークをクライアント・モードで開始する場合はtrue
        例外:
        IllegalArgumentException - 最初のハンドシェークが開始されてからモードを変更しようとした場合。
        関連項目:
        getUseClientMode()
      • getUseClientMode

        public abstract boolean getUseClientMode()
        ハンドシェーク時にクライアント・モードを使用するようにエンジンが設定されている場合はtrue。
        戻り値:
        クライアント・モードでハンドシェークを行う場合はtrue
        関連項目:
        setUseClientMode(boolean)
      • setNeedClientAuth

        public abstract void setNeedClientAuth​(boolean need)
        クライアント認証が必要なようにエンジンを構成します。 このオプションは、サーバー・モードのエンジンだけで使用します。

        エンジンのクライアント認証設定は、次のいずれかになります。

        • クライアント認証を必須にする
        • クライアント認証を要求する
        • クライアント認証を不要にする

        setWantClientAuth(boolean)の場合とは異なり、このオプションが設定されていて、かつクライアント認証情報が提供されない場合は、ネゴシエーションが停止し、エンジンは、終了プロシージャを開始します

        このメソッドを呼び出すと、このメソッドまたはsetWantClientAuth(boolean)によって行われた以前の設定がすべてオーバーライドされます。

        パラメータ:
        need - クライアント認証が必要な場合はtrueに、クライアント認証が不要な場合はfalseに設定される。
        関連項目:
        getNeedClientAuth(), setWantClientAuth(boolean), getWantClientAuth(), setUseClientMode(boolean)
      • setWantClientAuth

        public abstract void setWantClientAuth​(boolean want)
        クライアント認証を要求するようにエンジンを構成します。 このオプションは、サーバー・モードのエンジンだけで使用します。

        エンジンのクライアント認証設定は、次のいずれかになります。

        • クライアント認証を必須にする
        • クライアント認証を要求する
        • クライアント認証を不要にする

        setNeedClientAuth(boolean)とは異なり、このオプションが設定されていて、かつクライアントが自身に関する認証情報を提供しないことを選択した場合でも、ネゴシエーションは続行されます

        このメソッドを呼び出すと、このメソッドまたはsetNeedClientAuth(boolean)によって行われた以前の設定がすべてオーバーライドされます。

        パラメータ:
        want - クライアント認証が要求されている場合はtrueに、クライアント認証が不要な場合はfalseに設定される。
        関連項目:
        getWantClientAuth(), setNeedClientAuth(boolean), getNeedClientAuth(), setUseClientMode(boolean)
      • getWantClientAuth

        public abstract boolean getWantClientAuth()
        エンジンがクライアント認証を要求する場合はtrueを返します。 このオプションは、サーバー・モードのエンジンだけで使用します。
        戻り値:
        クライアント認証が要求された場合はtrue、クライアント認証が不要な場合はfalse。
        関連項目:
        setNeedClientAuth(boolean), getNeedClientAuth(), setWantClientAuth(boolean), setUseClientMode(boolean)
      • setEnableSessionCreation

        public abstract void setEnableSessionCreation​(boolean flag)
        このエンジンで新しいSSLセッションを確立できるかどうかを制御します。 セッションを作成できず、再開できる既存のセッションがない場合、ハンドシェークは成功しません。
        パラメータ:
        flag - セッションを作成できる場合はtrue (デフォルト)。既存のセッションを再開する場合はfalse
        関連項目:
        getEnableSessionCreation()
      • getEnableSessionCreation

        public abstract boolean getEnableSessionCreation()
        このエンジンで新しいSSLセッションを確立できる場合はtrueを返します。
        戻り値:
        セッションを作成できる場合はtrue (デフォルト)。既存のセッションを再開する場合はfalse
        関連項目:
        setEnableSessionCreation(boolean)
      • getSSLParameters

        public SSLParameters getSSLParameters()
        このSSLEngineで有効なSSLParametersを返します。 返されるSSLParametersの暗号化方式群とプロトコルは、常にnull以外です。
        戻り値:
        このSSLEngineで有効なSSLParameters。
        導入されたバージョン:
        1.6
      • setSSLParameters

        public void setSSLParameters​(SSLParameters params)
        このエンジンにSSLParametersを適用します。

        これは次のことを意味します。

        • params.getCipherSuites()がnull以外の場合は、その値を使用してsetEnabledCipherSuites()が呼び出される。
        • params.getProtocols()がnull以外の場合は、その値を使用してsetEnabledProtocols()が呼び出される。
        • params.getNeedClientAuth()またはparams.getWantClientAuth()trueを返した場合は、それぞれsetNeedClientAuth(true)setWantClientAuth(true)が呼び出される。それ以外の場合はsetWantClientAuth(false)が呼び出される。
        • params.getServerNames()がnull以外の場合、エンジンはサーバー名をその値で構成する。
        • params.getSNIMatchers()がnull以外の場合、エンジンはSNIマッチャをその値で構成する。
        パラメータ:
        params - パラメータ
        例外:
        IllegalArgumentException - setEnabledCipherSuites()またはsetEnabledProtocols()の呼出しが失敗した場合
        導入されたバージョン:
        1.6
      • getApplicationProtocol

        public String getApplicationProtocol()
        この接続でネゴシエートされた最新のアプリケーション・プロトコル値を返します。

        基になるSSL/TLS/DTLS実装でサポートされている場合、RFC 7301、アプリケーション層プロトコル・ネゴシエーション(ALPN)などのアプリケーション・ネーム・ネゴシエーション・メカニズムは、ピア間のアプリケーション・レベルの値をネゴシエートできます。

        実装要件:
        このクラスの実装は、UnsupportedOperationExceptionをスローし、他のアクションを実行しません。
        戻り値:
        アプリケーション・プロトコルがこの接続に使用されるかどうかまだ判定されていない場合はnull、アプリケーション・プロトコル値が使用されない場合は空のString、値が正常にネゴシエートされた場合は空のアプリケーション・プロトコルString
        例外:
        UnsupportedOperationException - ベースとなるプロバイダがこの操作を実装していない場合。
        導入されたバージョン:
        9
      • getHandshakeApplicationProtocol

        public String getHandshakeApplicationProtocol()
        現在進行中のSSL/TLSハンドシェイクでネゴシエートされたアプリケーション・プロトコル値を返します。

        getHandshakeSession()と同様に、接続はハンドシェイクの途中にある可能性があります。 アプリケーション・プロトコルはまだ利用可能であるかもしれないし、利用可能でないかもしれません。

        実装要件:
        このクラスの実装は、UnsupportedOperationExceptionをスローし、他のアクションを実行しません。
        戻り値:
        アプリケーション・プロトコルがこのハンドシェイクに使用されるかどうかまだ判定されていない場合はnull、アプリケーション・プロトコル値が使用されない場合は空のString、値が正常にネゴシエートされた場合は空ではないアプリケーション・プロトコルString
        例外:
        UnsupportedOperationException - ベースとなるプロバイダがこの操作を実装していない場合。
        導入されたバージョン:
        9
      • setHandshakeApplicationProtocolSelector

        public void setHandshakeApplicationProtocolSelector​(BiFunction<SSLEngine,List<String>,String> selector)
        SSL/TLS/DTLSハンドシェイクのアプリケーション・プロトコル値を選択するコールバック関数を登録します。 この関数は、SSLParameters.setApplicationProtocolsを使用して指定された値をオーバーライドし、次の型パラメータをサポートします:
        SSLEngine
        最初の引数は、ハンドシェーク・セッションや構成を含め、現在のSSLEngineを検査できるようにします。
        List<String>
        関数の第2引数は、TLSピアによって通知されたアプリケーション・プロトコル名をリストします。
        String
        関数の結果はアプリケーションのプロトコル名であり、宣言された名前のどれも受け入れられないことを示すためにはnullです。 戻り値が空のStringの場合、アプリケーション・プロトコルの指示は使用されません。 戻り値がnull (値が選択されていない)またはピアによって宣言されていない値である場合、基になるプロトコルは、実行するアクションを決定します。 (たとえば、ALPNは"no_application_protocol"アラートを送信し、接続を終了します。)
        たとえば、次の呼び出しは、TLSハンドシェイク・パラメータを調べてアプリケーション・プロトコル名を選択するコールバック関数を登録します:
        
             serverEngine.setHandshakeApplicationProtocolSelector(
                 (serverEngine, clientProtocols) -> {
                     SSLSession session = serverEngine.getHandshakeSession();
                     return chooseApplicationProtocol(
                         serverEngine,
                         clientProtocols,
                         session.getProtocol(),
                         session.getCipherSuite());
                 });
         
        APIの注:
        このメソッドは、TLSハンドシェイクが開始される前にTLSサーバー・アプリケーションによって呼び出される必要があります。 また、このSSLEngineは、コールバック関数で選択されたアプリケーション・プロトコルと互換性のあるパラメータで構成する必要があります。 たとえば、暗号スイートの選択肢を誤ると、適切なアプリケーション・プロトコルが得られない可能性があります。 SSLParametersを参照してください。
        実装要件:
        このクラスの実装は、UnsupportedOperationExceptionをスローし、他のアクションを実行しません。
        パラメータ:
        selector - コールバック関数、またはコールバック機能を無効にする場合はnullを返します。
        例外:
        UnsupportedOperationException - ベースとなるプロバイダがこの操作を実装していない場合。
        導入されたバージョン:
        9
      • getHandshakeApplicationProtocolSelector

        public BiFunction<SSLEngine,List<String>,String> getHandshakeApplicationProtocolSelector()
        SSL/TLS/DTLSハンドシェイク中にアプリケーション・プロトコル値を選択するコールバック関数を取得します。 関数型パラメータについては、setHandshakeApplicationProtocolSelectorを参照してください。
        実装要件:
        このクラスの実装は、UnsupportedOperationExceptionをスローし、他のアクションを実行しません。
        戻り値:
        コールバック関数。何も設定されていない場合はnull。
        例外:
        UnsupportedOperationException - ベースとなるプロバイダがこの操作を実装していない場合。
        導入されたバージョン:
        9