ヘッダーをスキップ

Oracle Containers for J2EE セキュリティ・ガイド
10g(10.1.3.4.0)

B50832-01
目次
目次
索引
索引

戻る 次へ

16 クライアント接続用Oracleセキュリティ

この章では、クライアントのOracleセキュリティの機能について説明します。この機能は、主に、クライアントHTTP接続にSecure Sockets Layer(SSL)機能とHTTPClientパッケージの機能を提供し、標準的なJava Secure Socket Extension(JSSE)の使用をサポートします。また、HTTPクライアントの非SSL認証機能を説明する項が含まれています。この章では、OC4JがWebリスナー(スタンドアロンのOC4Jなど)であるか、OC4JがOracle HTTP Serverの背後にある状況で、SSLを使用するJavaアプリケーションについて説明します。
この章の内容は次のとおりです。

非SSLクライアント認証の使用方法

この章では、主にクライアント・セキュリティ用HTTPSについて説明しています。ただし、一部のHTTPクライアントAPIは、非SSL認証用にクライアントで使用できます。ライブラリを使用して、リクエスト・ヘッダーにBasic、DigestおよびNTLMの認証情報を含めるHTTPリクエストを作成できます。この項では、HTTPClientパッケージを使用してこれらのタイプのリクエストを作成する方法を説明します。HTTPクライアントAPIの詳細は、『Oracle Application Server HTTPClient Java API Reference』を参照してください。

Basicベース・クライアント認証

HTTPクライアントを使用して、Basic認証を要求するサーバー・リソースにアクセスするためのHTTPリクエストを作成できます。次の例は、リクエストの作成、およびリクエストでaddBasicAuthorizationメソッドを使用してレルム、ユーザー名およびパスワードを含める方法を示しています。

URL url = new URL("http://localhost:1234");

HTTPConnection client = new HTTPConnection(url);

try {
   client.addBasicAuthorization("realm_name", "user", "password");
   HTTPResponse response = client.Get(url.getFile());
   //assertEquals(200, response.getStatusCode());
}
finally {
   client.stop();
}

レルムは、特定のサーバー下にある様々なURLをグループ化するサーバー指定文字列であり、サーバーによって認証チャレンジが発行された場合に正しい情報を選択するために使用されます。レルムを使用しないスキームでは、レルムを空の文字列("")にする必要があります。

Digestベース・クライアント認証

HTTPクライアントを使用して、Digest認証を要求するリソースにアクセスするためのHTTPリクエストを作成できます。Digest認証メカニズムでは、クライアントが自己認証を行うために示すパスワードが、MD5ダイジェストを使用して暗号化されます。これは、リクエスト・メッセージで送信されます。ユーザーからは、Digest認証はBasic認証と同じように動作するように見えます。次の例は、リクエストの作成、およびリクエストでaddDigestAuthorizationメソッドを使用してレルム、ユーザー名およびパスワードを含める方法を示しています。

HTTPConnection client = new HTTPConnection(url);

try {
   client.addDigestAuthorization("ProxyAuthDigestSchemeTestServlet",
      validUserName,validPassword);
   HTTPResponse response = client.Get(url.getFile());
   // assertEquals(200, response.getStatusCode());
}
finally {
   client.stop();
}

レルムは、特定のサーバー下にある様々なURLをグループ化するサーバー指定文字列であり、サーバーによって認証チャレンジが発行された場合に正しい情報を選択するために使用されます。レルムを使用しないスキームでは、レルムを空の文字列("")にする必要があります。

NTLMベース・クライアント認証

NTLMは、Microsoftのブラウザ、プロキシおよびサーバーで使用される、独自のチャレンジ/レスポンス認証プロトコルです。NTLMを使用するクライアントは、パスワードを送信せずに、サーバーに対してアイデンティティを証明できます。NTLMは接続指向プロトコルです。接続が認証されると、接続がオープンな間はその他の資格証明は不要です。

NTLMでは、NTドメイン名によってユーザー名が修飾されます。アカウント識別子は¥です。NTドメインは、ユーザー名の前にNTドメイン名とバックスラッシュを付けることで、HTTPクライアントで指定できます。たとえば、NTドメインがOPERATIONSでユーザー名がjsmithの場合、完全修飾ユーザー名はOPERATIONS¥jsmithです。

NTドメインが指定されていない場合は、デフォルト(設定されている場合)をそれとみなします。デフォルトのNTドメインは、システム・プロパティHTTPClient.ntlm.defaultDomainNameを使用してHTTPクライアントで設定されます。NTドメインなしでユーザー名が指定されており、デフォルトのNTドメインがHTTPクライアントで定義されていない場合、NTLM保護されているサーバーでは、独自のデフォルトNTドメインがそれとみなされます。

NTLM保護されているリソース・サーバーに接続するには、NTLM資格証明をHTTPクライアントのAuthorizationInfo資格証明ストアに追加します。Basic認証やDigest認証の場合のように、NTLMサーバーによってチャレンジが行われると、HTTPクライアントは自動的に資格証明ストアに問い合せます。資格証明は、次の方法のいずれかで資格証明ストアに追加できます。HTTP Connectionインスタンスを使用する方法は次のとおりです。

HTTPConnection conn = new HTTPConnection( myHost, myPort );
conn.addNtlmAuthentication( myUsername, myPassword );

AuthorizationInfoクラスを使用して直接追加する方法は次のとおりです。

AuthorizationInfo.addNtlmAuthentication( myHost, myPort, myUsername, myPassword )

次の例は、リクエストの作成、およびリクエストでaddNtlmAuthenticationメソッドを使用してユーザー名およびパスワードを含める方法を示しています。

HTTPConnection conn = new HTTPConnection( myHost, myPort );
conn.addNtlmAuthentication( myUsername, myPassword );
HTTPResponse response = conn.Get( "/index.htm" );
int status = response.getStatusCode();
assertEquals( 200, status );


注意

Basic認証などの認証スキームで指定されるため、レルムはNTLMに適用されません。NTLMチャレンジにはレルム・ディレクティブは含まれません。そのため、すべてのNTLM資格証明は、HTTPクライアント内の同じ空の("")レルムの一部とみなされます。 


NTLM保護されているプロキシ・サーバーへの接続方法

プロキシ・サーバーでも、クライアント認証にNTLMが使用されることがあります。ただし、リクエスト指向の認証とは異なり、NTLMクライアントは、リソース・サーバーではなくプロキシとの接続のみを認証します。

NTLM保護されているプロキシ・サーバーに接続するには、NTLM資格証明をHTTPクライアントのAuthorizationInfo資格証明ストアに追加します。Basic認証やDigest認証の場合のように、NTLMサーバーによってチャレンジが行われると、HTTPクライアントは自動的に資格証明ストアに問い合せます。資格証明は、AuthorizationInfoを使用して資格証明ストアに直接追加することのみ可能です。次に例を示します。

AuthorizationInfo.addNtlmAuthentication( myProxyHost, myProxyPort, myUsername,
   myPassword)

次に、保護されているプロキシ・サーバーにNTMLを使用して接続するクライアントの例を示します。

HTTPConnection conn = new HTTPConnection( myHost, myPort );
conn.setCurrentProxy( myProxyHost, myProxyPort );
AuthorizationInfo.addNtlmAuthentication( myProxyHost, myProxyPort, myUsername,
   myPassword, conn.getContext() )
HTTPResponse response = conn.Get( "/index.htm" );
int status = response.getStatusCode();
assertEquals( 200, status );

HTTPSおよびクライアント

HTTPSは、クライアントとサーバー間の対話の保護に不可欠です。多数のサーバー・アプリケーションの場合、HTTPSはWebサーバーにより処理されます。ただし、他のWebサーバーへの接続を開始するWebアプリケーションなど、クライアントとして機能するアプリケーションには、サーバーとの間で情報をセキュアにやり取りするために独自のHTTPS実装が必要です。HTTPClientパッケージまたはSun社のjava.netパッケージに精通しているJavaアプリケーション開発者は、HTTPSを使用してクライアントとサーバーとの対話を簡単に保護できます。

OracleクライアントHTTPS機能は、完全なHTTPクライアント・ライブラリを提供する、HTTPClientパッケージのHTTPConnectionクラスをベースにしています。HTTPConnectionクラスは、SSLを使用するかどうかを問わず、HTTPを使用する新規接続の作成に使用されます。


重要

HTTPClientのOracle実装は、ベースになったオリジナルのオープン・ソース・バージョンから変更されています。Oracleバージョンは別個の製品と考えてください。類似点は多数残っていますが、この2つには必ずしも相互に互換性があるわけではありません。 


関連項目

  • JSSEとjava.netパッケージのドキュメントは、次のURLを参照してください。

    http://java.sun.com/products/jsse/index.jsp
    
    http://java.sun.com/j2se/1.4.2/docs/api/
    
    
  • 『Oracle Application Server HTTPClient Java API Reference』(HTTPClientパッケージ用のJavadoc)

 

クライアント・サイドHTTPS機能の概要

OracleクライアントHTTPSは、HTTPClientパッケージのHTTPConnectionクラスを拡張し、暗号スイートの選択、Oracle Wallet Managerによるセキュリティ資格証明管理、セキュリティ対応アプリケーションのサポート、後述するその他の機能などのSSL機能を提供します。OracleクライアントHTTPSでは、クライアントとサーバー間のHTTP 1.0およびHTTP 1.1接続がサポートされます。

HTTPClientでは、JSSEおよびOracle Java SSLという2つのSSL実装がサポートされます。ただし、後者はOC4J 10.1.3.1実装で非推奨であり、将来のリリースでサポートされなくなります。そのため、JSSEを使用することをお薦めします。

OracleクライアントHTTPSでは、HTTPClientパッケージに組み込まれている機能に加えて次の機能がサポートされます。

さらに、HTTPClientパッケージを使用して次の機能がサポートされます。

次項では、次の機能について説明します。

サポートされているキーストア形式

JSSEを使用する場合、Oracle JSSE実装(OraclePKIProvider)とPKCS12またはSSO(自動ログイン)Oracle Walletの組合せか、デフォルトのSun社のJSSE実装とJKS形式キーストアの組合せを使用できます。(Oracle Java SSLは、テキスト形式のOracle Walletのみサポートします。)

PKCS12またはSSO Walletのいずれかを使用する場合、資格証明情報は暗号化されます。主な違いは、SSO Walletを使用する場合、アクセス時にWalletを開くためにWalletパスワードを指定する必要がないことです。

JKSとPKCS12は標準形式です。SSO WalletはOracle独自の形式です。

関連項目

  • PKCS12とSSO/自動ログインWalletの作成と使用の詳細は、『Oracle Application Server管理者ガイド』(Walletと資格証明の管理の章)を参照してください。

 

確立されたSSL接続に関する情報へのアクセス

Oracle HTTPClientパッケージのHTTPConnectionクラスにあるgetSSLSession()メソッドを使用すると、確立されたSSL接続に関する情報にアクセスできます。接続の確立後は、接続に使用された暗号スイート、ピア証明連鎖および現行の接続に関するその他の情報を取得できます。

java.net.URLフレームワークのサポート

HTTPClientパッケージは、HTTPClient.HttpUrlConnectionクラスによりjava.net.URLフレームワークの基本サポートを提供します。ただし、OracleクライアントHTTPSの機能の多くは、システム・プロパティを介してのみサポートされます。

システム・プロパティを介してのみサポートされる機能は、次のとおりです。

SSL暗号スイート

データがSSL接続を介して流れる前に、接続の両端がデータ送信に使用する共通アルゴリズムを折衝する必要があります。混在型のセキュリティ機能を提供するために結合されているアルゴリズムのセットは、暗号スイートと呼ばれます。SSL接続の参加者は、特定の暗号スイートを選択すると適切な通信レベルを確立できます。

通常は、次の優先順位に従う必要があります。

OC4J 10.1.3.1リリースでJSSEがサポートする暗号スイートを、デフォルトの優先順序で次に示します。このリストで、"*"が付いたスイートは、デフォルトで有効になる暗号スイートを表し、"**"が付いたスイートは、Sun社のJCE Unlimited Strength Jurisdiction Policy Filesのインストールが必要な暗号スイートを表しています。NULL暗号化の場合、SSLは認証とデータ整合性のためにのみ使用されることに注意してください。


注意

HTTPClientは、サポートされる暗号スイートのサブセットを選択的に有効にする手段を提供しません。 


SSL_RSA_WITH_RC4_128_MD5 *
SSL_RSA_WITH_RC4_128_SHA *
TLS_RSA_WITH_AES_128_CBC_SHA *
TLS_DHE_RSA_WITH_AES_128_CBC_SHA *
TLS_DHE_DSS_WITH_AES_128_CBC_SHA *
SSL_RSA_WITH_3DES_EDE_CBC_SHA *
SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA *
SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA *
SSL_RSA_WITH_DES_CBC_SHA *
SSL_DHE_RSA_WITH_DES_CBC_SHA *
SSL_DHE_DSS_WITH_DES_CBC_SHA *
SSL_RSA_EXPORT_WITH_RC4_40_MD5 *
SSL_RSA_EXPORT_WITH_DES40_CBC_SHA *
SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA *
SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA *
TLS_RSA_WITH_AES_256_CBC_SHA **
TLS_DHE_RSA_WITH_AES_256_CBC_SHA **
TLS_DHE_DSS_WITH_AES_256_CBC_SHA **
SSL_RSA_WITH_NULL_MD5
SSL_RSA_WITH_NULL_SHA
SSL_DH_anon_WITH_RC4_128_MD5
TLS_DH_anon_WITH_AES_128_CBC_SHA
TLS_DH_anon_WITH_AES_256_CBC_SHA **
SSL_DH_anon_WITH_3DES_EDE_CBC_SHA
SSL_DH_anon_WITH_DES_CBC_SHA
SSL_DH_anon_EXPORT_WITH_RC4_40_MD5
SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA

関連項目

  • JSSEに関する一般情報は、次のURLを参照してください。

    http://java.sun.com/j2se/1.4.2/docs/guide/security/jsse/
    JSSERefGuide.html
 

サポートされているデフォルトのシステム・プロパティ

この項では、キーストアとトラストストアに対してサポートされる標準のJavaシステム・プロパティについて説明します。(java.net.URLフレームワークのユーザーがセキュリティ資格証明情報を設定するには、これらのプロパティを使用する必要があります。)OracleクライアントHTTPSでは、次のプロパティが認識されます。

プロパティjavax.net.ssl.KeyStore

このプロパティは、キーストアとして使用するキーストア・ファイルまたはWalletファイルの場所と名前を指定します。

プロパティjavax.net.ssl.KeyStorePassword

このプロパティは、キーストア(キーストア・ファイルまたはWalletファイル)を開くために必要なパスワードを指定できます。次に例を示します。

javax.net.ssl.keyStorePassword=welcome1


重要

キーストアのパスワードをJavaシステム・プロパティとして格納すると、環境によってはセキュリティ上のリスクが生じる可能性があります。このリスクを回避するために、次のいずれかの代替策を使用します。

  • アプリケーションで相互認証が必要ない場合は、パスワードを必要としないSSO Walletを使用します。

  • パスワードが必要な場合は、クリアテキスト・ファイルに格納しません。かわりに、System.setProperty()メソッドを使用して、HTTPConnectionを起動する前にプロパティを動的にロードします。ハンドシェイクの完了後に、このプロパティを設定解除します。

 

プロパティjavax.net.ssl.keyStoreType

このプロパティは、キーストアで使用されるファイルのタイプを指定します。Oracle JSSE実装(OraclePKIProvider)の場合、PKCS12またはSSOを指定できます。デフォルトのSun社のJSSE実装の場合、JKSを指定できます。

関連項目

  • PKCS12のタイプの詳細は、『Oracle Application Server管理者ガイド』に記載されているSSLの概要を参照してください。

 

プロパティjavax.net.ssl.trustStore

このプロパティは、javax.net.ssl.keyStoreと同様に使用されます。このプロパティは、トラストストア(クライアントが暗黙的に受け入れる信頼できる認証局を格納するファイル)として使用するキーストア・ファイルまたはWalletファイルの場所と名前を指定します。

プロパティjavax.net.ssl.trustStorePassword

このプロパティは、javax.net.ssl.keyStorePasswordと同様に使用されます。このプロパティは、トラストストア(キーストア・ファイルまたはWalletファイル)を開くために必要なパスワードを指定します。

プロパティjavax.net.ssl.trustStoreType

javax.net.ssl.keyStoreTypeと同様に、このプロパティは、トラストストアで使用するファイル・タイプを指定します。Oracle JSSE実装の場合はPKCS12またはSSOで、Sun社のJSSE実装のデフォルトの場合はJKSです。

JSSEとHTTPClientの使用

この項では、JSSEを使用するHTTPSクライアント接続のOracle Application Serverサポートについて説明します。この項の内容は次のとおりです。

JSSEの使用の前提条件

OracleクライアントHTTPSでJSSEを使用する場合、次の要件があります。

JSSEを使用するHTTPClientの構成

Oracle Application Serverは、JSSEを使用してHTTPSクライアント接続をサポートします。クライアントでは、次の手順に従い、基礎となるSSLプロバイダとしてJSSEを使用するようにHTTPClientを構成できます。

  1. Sun社のkeytoolを使用してトラストストアを作成します。

    関連項目

    • keytoolの使用方法の詳細は、次のURLを参照してください。

      http://java.sun.com/j2se/1.3/docs/tooldocs/win32/
      keytool.html
     

  2. トラストストアのプロパティを設定します。JSSEの使用を希望するクライアントでは、javax.net.ssl.trustStoreプロパティを介してクライアント・トラストストアの位置を指定する必要があります。クライアントでjavax.net.ssl.keyStoreプロパティを設定する必要はありません。

  3. 静的メソッドSSLSocketFactory.getDefault()をコールして、JSSE SSLソケット・ファクトリ(javax.net.ssl.SSLSocketFactoryインスタンス)を取得します。

  4. HTTPClient接続(HTTPConnectionインスタンス)を作成します。

  5. SSLのJSSE実装を使用するようにHTTPClient接続を構成します。JSSEを使用するようにHTTPClientを構成するには、次のいずれかの方法があります。

    • 接続ごと)クライアントでHTTPConnectionインスタンスの次のメソッドをコールします。その際、手順3のgetDefault()メソッドにより取得されたJSSE SSLソケット・ファクトリを指定します。

      void setSSLSocketFactory(SSLSocketFactory factory)
      
      

      この場合、SSLソケット・ファクトリはこの接続インスタンス用にのみ設定されます。その技術的方法については、後出の例16-1に示されています。

    • VM全体)クライアントでHTTPConnectionクラスの次の静的メソッドをコールします。

      void HttpConnection.setDefaultSSLSocketFactory(SSLSocketFactory factory)
      
      

      この場合、メソッドを別の設定で再コールしないかぎり、SSLソケット・ファクトリがJava VM内のすべての接続インスタンスに対して設定されます。このメソッドは、対象となるHTTPConnectionインスタンスをインスタンス化する前にコールする必要があります。

  6. HTTPSデータを送信する前に、HTTPConnectionクラスのconnect()メソッドを呼び出す必要があります。これにより、接続では、データを暗号化して送信する前に、クライアントとサーバー間に発生する必要のあるSSLハンドシェイキングを検証できます。Oracle実装の場合、HTTPConnectionクラスのGet()メソッドなど、HTTPメソッドの呼び出し時にこのメソッドが暗黙的に呼び出されます。また、データ送信の前にコール元アプリケーションがSSLセッション情報を必要とする場合、connect()メソッドを明示的に呼び出すと便利です。「追加の接続情報の検証」を参照してください。

  7. HTTPConnectionインスタンスを通常の方法で使用します。この時点で、クライアントはJSSEとともにHTTPClientを使用するように設定されています。追加構成は不要であり、基本的な使用方法は同じです。

    例16-1    HTTPClientでのJSSEの使用

    public void obtainHTTPSConnectionUsingJSSE() throws Exception
    {
       // set the truststore to the location of the client's truststore file
       // this value specifies the certificate authorities the client accepts
       System.setProperty("javax.net.ssl.trustStore", KEYSTORE_FILE);
       // creates the HTTPS URL
       URL testURL = new URL("https://" + HOSTNAME + ":" + HTTPS_PORTNUM);
       // call SSLSocketFactory.getDefault() to obtain the default JSSE implementation
       // of an SSLSocketFactory
       SSLSocketFactory socketFactory =
                        (SSLSocketFactory)SSLSocketFactory.getDefault();
       HTTPConnection connection = new HTTPConnection(testURL);
    
       // configure HTTPClient to use JSSE as the underlying
       // SSL provider
       connection.setSSLSocketFactory(socketFactory);
       // call connect to setup SSL handshake
       try
       {
           connection.connect();
       }
       catch (IOException e)
       {
           e.printStackTrace();    }
    
       HTTPResponse response = connection.Get("/index.html");
       
    }
    


    注意

    • SSLソケット・ファクトリを指定しなかった状態で、Oracle Java SSLが指定されていないか、アプリケーションのクラスパスにOracle Java SSLクラスが見つからない場合、デフォルトでJSSEが使用されます。SSLソケット・ファクトリが指定されていない状態でOracle Java SSLが指定されている場合は、Oracle Java SSLクラスがクラスパスで検出され、デフォルトでOracle Java SSLが使用されます。「HTTPClientに対するSSL実装としてのOracle Java SSLの指定」を参照してください。

    • JSSE SSL実装はスレッド・セーフではありません。

     

SSLホスト名検証のHTTPClientサポート

SSLでは、サーバーから提示された証明連鎖が有効で、クライアントが信頼できる証明書が1つ以上含まれているかどうかが検証されますが、悪意のある第三者による偽装は防止されません。この問題に対処するHTTPS規格は、HTTPSサーバーがそのホスト名に対して発行された証明書を持つように求めています。このため、クライアントはSSL接続の確立後に、この検証を実行する必要があります。

ホスト名検証機能(javax.net.ssl.HostnameVerifier implementation)は、HTTPClientによって使用されます。これにより、保護されているサーバーへアクセスする際に使用されるURIのホスト名と、SSL証明書のホスト名が一致するかどうかが検証されます。これは、介入者攻撃の検出に役立ちます。HTTPClientは、SSLセッションを確立した直後にHostnameVerifierインスタンスを呼び出し、ホスト名の不一致が検出された場合はjavax.net.ssl.SSLPeerUnverifiedExceptionをスローします。


重要

独自のHostnameVerifierを実装することも、Oracle提供のインスタンス(後述)を使用することもできます。実装する場合、引数なしのコンストラクタが必要です。 


関連項目

  • javax.net.ssl.HostnameVerifierのJavadocは、次のサイトから入手できます。

    http://java.sun.com/j2se/1.4.2/docs/api/
    
 

この項では、この機能を有効にして使用する方法を説明します。この項の内容は次のとおりです。

ホスト名検証を実行するには、次に説明するシステム・プロパティ設定またはプログラム設定が必要です。

システム・プロパティ設定によるホスト名検証の有効化

コードを変更することなくホスト名検証を有効にするには、システム・プロパティHTTPClient.defaultHostnameVerifierに、クラスパス内にあるホスト名検証機能実装の完全修飾されたクラス名を設定します。

設定する場合、適切なクラスの名前(引数なしのコンストラクタ付きのjavax.net.ssl.HostnameVerifier実装)を指定する必要があります。

プログラムによるホスト名検証の有効化

検証に使用するjavax.net.ssl.HostnameVerifierインスタンスを指定することにより、次に示すHTTPConnectionクラスのメソッドを使用して、ホスト名検証をプログラムによって有効にすることができます。

Oracle標準のホスト名検証機能の使用

HTTPClientパッケージ内に、ホスト名検証機能の実装のStandardHostnameVerifierが用意されています。

StandardHostnameVerifierは、サイトのアイデンティティをチェックする標準的なホスト名一致規則を実装し、次の機能を備えています。

StandardHostnameVerifierには、次のメソッドがあります。

前述のように、プログラムまたはシステム・プロパティ設定により、StandardHostnameVerifierをホスト名検証機能として指定できます。デフォルトのホスト名検証機能として設定するには、次のシステム・プロパティ設定などを使用します。

HTTPClient.defaultHostnameVerifier=HTTPClient.StandardHostnameVerifier;

追加の接続情報の検証

HTTPConnectionクラスのconnect()が呼び出された後で、HTTPConnectionクラスのgetSSLSession()メソッドから返されるjavax.net.ssl.SSLSessionオブジェクト内で検出されたデータを使用して、(ホスト名検証以外の)追加の検証を実行できます。

この検証を実行するためには、次のように、データを転送することなくサーバーへの接続を確立します。

httpsConnection.connect();

接続の確立後は、次のように接続情報(この場合はサーバーの証明連鎖)が取得されます。

peerCerts = (httpsConnection.getSSLSession()).getPeerCertificateChain();

最後に、次のようにサーバー証明書の一般名が取得されます。

String peerCertDN = peerCerts[0].getSubjectDN().getName();
peerCertDN = peerCertDN.toLowerCase();

(ユーザーの証明書は配列の先頭に、ルートCAの証明書は末尾にあります。)

証明書名がサーバーへの接続に使用されたホスト名と異なる場合は、次のように接続が異常終了します。

if(peerCertDN.lastIndexOf("cn="+ hostname) == -1)
{
    System.out.println("Certificate for " + hostname + " is issued to " +
        peerCertDN);
    System.out.println("Aborting connection");
        System.exit(-1);
}


注意

前の項で説明したように、ホスト名検証機能を使用することをお薦めします。 


Oracle Java SSLからJSSEへの移行

前述のように、OC4J 10.1.3.1以降の実装の場合、Oracle Java SSLではなくJSSEを使用することをお薦めします。Oracle Java SSLは10.1.3.1実装で非推奨であり、将来のリリースでサポートされなくなります。この項では、SSL機能に対してOracle Java SSLのかわりにJSSEを使用するようクライアント・コードを変更する方法を説明します。

JSSEへの移行のコード・サンプル

この項では、JSSEを使用する新しいSSLソケット・ファクトリを作成する手順を示すため、以前にOracle Java SSLで使用していたものと同じコードと比較しながら、コード・サンプルを説明します。java.security.Keystoreクラスと様々なjavax.net.sslクラスは、ピア証明の検証用にキーストアまたはWalletを開き、Oracle固有のセキュリティ・ポリシーを適用する場合に使用されます。

関連項目

  • KeystoreのJavadocおよびjavax.net.sslクラスは、次のサイトから入手できます。

    http://java.sun.com/j2se/1.4.2/docs/api/
    
 

次に、説明と比較を加えながら手順を説明します。

  1. SSLプロバイダを登録します。プロバイダがJDKのjre/lib/security/java.securityプロパティ・ファイルに静的に設定されている場合、この手順は必要ありません。

    Oracle Java SSL用の従来のコード: なし

    JSSE用の新しいコード:

    Security.insertProviderAt(new oracle.security.ssl.OraclePKIProvider(), 1);
    
    

    java.security.Securityクラスの静的なinsertProviderAt()メソッドは、指定された優先順位に新しいプロバイダを追加します。この順位は、要求されたアルゴリズムでプロバイダを検索する優先順位を表します。1が最も優先順位が高くなります。Oracleセキュリティ・ポリシーを強制する場合、OraclePKIProviderを使用します。プロバイダを設定すると、SSL機能に対して標準のJSSEクラスを使用できます。

  2. キーストア、Walletまたは信頼できる認証局をロードします。

    Oracle Java SSL用の従来のコード:

    OracleSSLCredential cred = new OracleSSLCredential();
    cred.loadWallet("walletpath", "password");
    
    

    JSSE用の新しいコード:

    KeyStore myWallet = KeyStore.getInstance("keystoretype","OraclePKI");
    FileInputStream istr = new FileInputStream("pathtowallet");
    myWallet.load(istr, password);
    
    

    Keystoreクラスの静的なgetInstance()メソッドは、指定されたプロバイダから、指定されたキーストア・タイプに対するキーストア・オブジェクトを作成します。プロバイダとしてOraclePKIを使用します。

    このサンプルの場合、keystoretypeは、PKCS12またはSSOです。pathtowalletは、キーストアまたはWalletのパスおよびファイル名です。passwordは、パスワードのchar[]配列です。SSO Walletを使用する場合は、nullになります。

    Oracle Java SSLで使用したOracleSSLCredentialクラスは、JSSEでは使用しません。

  3. SSLソケット・ファクトリを作成します。

    Oracle Java SSL用の従来のコード:

    OracleSSLSocketFactory socketFactory = new OracleSSLSocketFactoryImpl();
    SocketFactory.setSSLCredentials(cred);
    
    

    JSSE用の新しいコード:

    TrustManagerFactory tmf = TrustManagerFactory.getInstance("OracleX509");
    tmf.init(trustCerts);
    TrustManager[] tmA = tmf.getTrustManagers();
    
    KeyManagerFactory kmf = KeyManagerFactory.getInstance("OracleX509");
    kmf.init(trustCerts, password);
    KeyManager[] kmA = kmf.getKeyManagers();
    
    SSLContext ctx = SSLContext.getInstance("SSL");
    ctx.init(kmA, tmA, null);
    SSLSocketFactory factory = ctx.getSocketFactory();
    
    

    SSL接続がピア証明連鎖を検証できるように、信頼マネージャを作成して設定します。SSL接続がユーザー証明書と秘密鍵にアクセスできるように、キー・マネージャを作成して設定します。キー・マネージャと信頼マネージャを使用して、SSLコンテキストを構成します。これは、新しいSSLソケット・ファクトリを作成する際に使用されます。SSLSocketFactoryインスタンスを作成すると、SSLソケットを作成する際に使用できます。

JSSEへの移行に関連する追加の変更

次に示す追加の変更をOracle Java SSLとJSSEの間で行うと、アプリケーションに影響する場合があります。

Oracle Java SSLの機能(非推奨)

Oracle Java SSLは、OC4J 10.1.3.1実装では非推奨ですが、サポートはされています。(将来のリリースではサポートされなくなる予定です。)

この項ではOracle Java SSL固有の機能について記載していますが、「Oracle Java SSLからJSSEへの移行」で説明しているように、JSSEへの移行をお薦めします。

この項の内容は次のとおりです。

HTTPClientに対するSSL実装としてのOracle Java SSLの指定

OC4J 10.1.3.1実装の場合、JDKのデフォルトのJSSE実装が、HTTPClientのデフォルトのSSL実装になりました。(これにより、HTTPClientの以前のデフォルトSSL実装であったOracle Java SSLは、今後非推奨となります。)

ただし、次の手順を実行すると、Oracle Java SSLをHTTPClientのデフォルトSSL実装として明示的に指定することができます。

  1. 次のシステム・プロパティ設定を指定します。

    HTTPClient.preferOracleSSL=true
    
    
  2. Oracle Java SSLクラスがクラスパス(oracle.security.ssl.OracleSSLSocketFactoryなど)内にあることを確認します。


    重要

    SSLソケット・ファクトリ(javax.net.ssl.SSLSocketFactory実装)が、HTTPConnectionsetSSLSocketFactory()メソッドによって明示的に指定されている場合、HTTPClient.preferOracleSSLプロパティの設定にかかわらず、指定されたファクトリに関連付けられたSSL実装が使用されます。 


Oracle Java SSLのOracleSSLCredentialクラス

Oracle Java SSLを使用するクライアントHTTPS接続をサポートするため、Oracle Java SSLクラスOracleSSLCredentialを使用するHTTPConnectionクラスに複数のメソッドが追加されていました。

Oracle Java SSLの場合、サーバーとクライアントを相互に認証する際にセキュリティ資格証明を使用します。OracleSSLCredentialは、base64またはDERエンコード証明書からユーザー証明書とトラスト・ポイントをロードする際に使用されます。(DERはX.690 ASN.1規格の一部で、Distinguished Encoding Rulesの略語です。)

Oracle Java SSL用のAPIでは、接続が確立される前にセキュリティ資格証明がHTTP接続に渡される必要があります。OracleSSLCredentialクラスは、これらのセキュリティ資格証明の格納に使用されます。通常、Oracle Wallet Managerにより生成されるWalletは、OracleSSLCredentialオブジェクトの移入に使用されます。または、OracleSSLCredentialクラスのAPIを使用して個々の証明書を追加できます。資格証明がすべて揃うと、HTTPConnectionクラスのsetSSLCredential()メソッドとの接続に使用されます。

Oracle Java SSLにおけるセキュリティ対応アプリケーションのサポート

OracleクライアントHTTPSでは、SSLを使用してセキュリティ対応アプリケーションのサポート機能が提供されます。セキュリティ対応アプリケーションでトラスト・ポイントが設定されていない場合は、SSLを使用すると、独自の検証を実行して、ピアから完全な証明連鎖が送信された場合にのみハンドシェイクを正常終了させることができます。アプリケーションでトラスト・ポイント・レベルまで認証する場合は、トラスト・ポイントの下の個々の証明書を認証する必要があります。

ハンドシェイクの完了後に、アプリケーションはSSLセッション情報を取得して、接続について追加の検証を実行する必要があります。

トラスト・ポイントのチェックを必要とするセキュリティ非対応アプリケーションでは、HTTPSのインフラストラクチャ内でトラスト・ポイントが設定されていることを確認する必要があります。

Oracle Java SSLでのHTTPClientの使用

この項では、HTTPClientおよびOracle Java SSLを使用してWebサーバーに接続し、GETリクエストを送信してWebページをフェッチするアプリケーションを示します。

サンプル・コード(Oracle Java SSL)

この項では、HTTPClientおよびOracle Java SSLを使用するサンプル・コードを示します。

import HTTPClient.HTTPConnection;
import HTTPClient.HTTPResponse;
import oracle.security.ssl.OracleSSLCredential;
import java.io.IOException;

public class HTTPSConnectionExample
{
    public static void main(String[] args)
    {
        if(args.length < 4)
        {
            System.out.println(
            "Usage: java HTTPSConnectionTest [host] [port] " +
            "[wallet] [password]");
            System.exit(-1);
        }

        String hostname = args[0].toLowerCase();
        int port = Integer.decode(args[1]).intValue();
        String walletPath = args[2];
        String password = args[3];

        HTTPConnection httpsConnection = null; 
        OracleSSLCredential credential = null;

        try
        {
            httpsConnection = new HTTPConnection("https", hostname, port);
        }
        catch(IOException e)
        {
            System.out.println("HTTPS Protocol not supported");
            System.exit(-1);
        }

        try
        {
            credential = new OracleSSLCredential();
            credential.setWallet(walletPath, password);
        }
        catch(IOException e)
        {
            System.out.println("Could not open wallet");
            System.exit(-1);
        }
        httpsConnection.setSSLCredential(credential);

        try
        {
            httpsConnection.connect();
        }
        catch (IOException e)
        { 
            System.out.println("Could not establish connection");
            e.printStackTrace();
            System.exit(-1);
        }

        javax.servlet.request.X509Certificate[] peerCerts = null;
        try
        {
            peerCerts =
              (httpsConnection.getSSLSession()).getPeerCertificateChain();
        }
        catch(javax.net.ssl.SSLPeerUnverifiedException e)
        { 
            System.err.println("Unable to obtain peer credentials");
            System.exit(-1);
        }

        String peerCertDN = 
          peerCerts[peerCerts.length -1].getSubjectDN().getName();
        peerCertDN = peerCertDN.toLowerCase();
        if(peerCertDN.lastIndexOf("cn="+ hostname) == -1)
        {
            System.out.println("Certificate for " + hostname + " is issued to "
              + peerCertDN); 
            System.out.println("Aborting connection");
            System.exit(-1);
        }

        try
        {
            HTTPResponse rsp = httpsConnection.Get("/");
            System.out.println("Server Response: ");
            System.out.println(rsp); 
        }
        catch(Exception e)
        {
            System.out.println("Exception occured during Get");
            e.printStackTrace();
            System.exit(-1);
        }
    }
}

Oracle Java SSLにおけるSSL資格証明の初期化

この例では、Oracle Wallet Managerにより作成されたWalletを使用して資格証明情報を設定します。

  1. 最初に、資格証明を作成し、Walletをロードします。

    mycredential = new OracleSSLCredential();
    mycredential.setWallet(wallet_path, password);
    
    
  2. 作成された資格証明は、HTTPConnectionインスタンス(ここでの名前はhttpsConnection)に、インスタンスのメソッドsetSSLCredential()を介して渡されます。このメソッドは、次のように、最初の手順で作成されたOracleSSLCredentialインスタンスを入力として取ります。

    httpsConnection.setSSLCredential(mycredential);
    
    

これにより、Walletに置かれた秘密鍵、ユーザー証明書およびトラスト・ポイントを接続に使用できます。

Oracle Java SSLでのシステム・プロパティ機能

「サポートされているデフォルトのシステム・プロパティ」では、Javaシステム・プロパティのkeyStorekeyStorePasswordkeyStoreTypetrustStoretrustStorePasswordtrustStoreTypeについて説明しています。この項では、Oracle Java SSL固有のjavax.net.ssl.keyStoreに関連する次の機能を説明します。

Oracle Java SSLの暗号スイートの指定

この項では、Oracle Java SSLの暗号スイートを指定する方法について説明します。

プロパティOracle.ssl.defaultCipherSuites

Oracle Java SSLの場合、Oracle.ssl.defaultCipherSuitesプロパティは、暗号スイートのカンマ区切りのリストに設定できます。次に例を示します。

Oracle.ssl.defaultCipherSuites=
            SSL_RSA_WITH_DES_CBC_SHA,
            SSL_RSA_EXPORT_WITH_RC4_40_MD5,
            SSL_RSA_WITH_RC4_128_MD5

このプロパティは、SSL接続を確立する前にOracle Java SSLを使用して設定できます。このプロパティに設定する暗号スイートは、新規HTTPS接続で有効な暗号スイートとして使用されます。

関連項目

 

メソッドsetSSLEnabledCipherSuites()

Oracle Java SSLの場合、パッケージHTTPClientHTTPConnectionクラスの次のメソッドを使用することにより、接続ごとに暗号スイートを設定することもできます。

これは、各配列要素で暗号スイートを指定するJava文字列配列を取ります。現在のSSL実装がこのメソッドをサポートするかどうかを示すブール値を返します。


注意

JSSEでHTTP接続ごとに暗号スイートを指定する方法はありません。 


関連項目

  • 追加情報は、『Oracle Application Server HTTPClient Java API Reference』 (Javadoc)を参照してください。

 

Oracle Java SSLでサポートされるSSL暗号スイート

Oracle Java SSLは、表16-1に示す暗号スイートをサポートします。NULL暗号化の場合、SSLは認証とデータ整合性のためにのみ使用されることに注意してください。

表16-1    Oracle Java SSLでサポートされる暗号スイート 
暗号スイート  認証  暗号化  ハッシュ関数
(ダイジェスト)
 

SSL_RSA_WITH_3DES_EDE_CBC_SHA 

RSA 

3DES EDE CBC 

SHA1 

SSL_RSA_WITH_RC4_128_SHA  

RSA 

RC4 128 

SHA1 

SSL_RSA_WITH_RC4_128_MD5 

RSA 

RC4 128 

MD5 

SSL_RSA_WITH_DES_CBC_SHA 

RSA 

DES CBC 

SHA1 

SSL_RSA_EXPORT_WITH_RC4_40_MD5  

RSA 

RC4 40 

MD5 

SSL_RSA_EXPORT_WITH_DES40_CBC_SHA  

RSA 

DES40 CBC 

SHA1 

SSL_DH_anon_WITH_3DES_EDE_CBC_SHA 

DH anon 

3DES EDE CBC 

SHA1 

SSL_DH_anon_WITH_RC4_128_MD5 

DH anon 

RC4 128 

MD5 

SSL_DH_anon_WITH_DES_CBC_SHA 

DH anon 

DES CBC 

SHA1 

SSL_DH_anon_EXPORT_WITH_RC4_40_MD5 

DH anon 

RC4 40 

MD5 

SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA  

DH anon 

DES40 CBC 

SHA1 

SSL_RSA_WITH_NULL_SHA 

RSA 

NULL 

SHA1 

SSL_RSA_WITH_NULL_MD5 

RSA 

NULL 

MD5 


戻る 次へ
Oracle
Copyright © 2003, 2008 Oracle Corporation.

All Rights Reserved.
目次
目次
索引
索引