ヘッダーをスキップ
Oracle Fusion Middlewareセキュリティ・ガイド
11gリリース1(11.1.1)
B56235-01
  目次
目次
索引
索引

戻る
戻る
 
次へ
次へ
 

20 Oracle HTTPClientセキュリティを使用した開発

Oracle HTTPClientセキュリティでは、パッケージHTTPClientを使用して、クライアントHTTP接続でSecure Sockets Layer(SSL)をサポートしています。この章では、HTTPClientの基本機能、システム・プロパティを使用してHTTPClientを構成する方法、および標準のJava Secure Socket Extension(JSSE)またはNTLM認証でHTTPClientを使用する方法について説明します。

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

JSSEの一般情報は、http://java.sun.com/javase/6/docs/technotes/guides/security/jsse/JSSERefGuide.htmlを参照してください。

20.1 Oracle HTTPClientセキュリティの概要

Oracle HTTPClientセキュリティは、パッケージHTTPClient.HTTPConnectionを実装し、ソースとターゲット間のHTTP接続(セキュアな接続またはそれ以外の接続)の作成を可能にする関数の包括的なセットを提供します。クラスHTTPClientのOracleによる実装は、そのベースであるオリジナルのオープン・ソース・バージョンとは異なります。それらの間には多数の類似点がありますが、この2つの実装は必ずしも互換ではありません。

JSSEおよびjava.netの詳細は、次のリンクの情報を参照してください。

20.2 Oracle HTTPClientセキュリティの機能

Oracle HTTPSクライアントによってセキュリティ認識アプリケーションに提供される主な機能は、次のとおりです。

Oracle HTTPClientでは、クライアントとサーバー間の通信に対するプロトコルHTTP 1.0およびHTTP 1.1の使用、およびJSSE SSLの実装がサポートされています。OraclePKIProviderをJVMに追加しないとOracleウォレットは使用できないことに注意してください。「JSSEを使用する場合の前提条件」を参照してください。

次の4つの項で、Oracle HTTPClientセキュリティによってサポートされる主要な機能について詳しく説明します。

20.2.1 キーストアの形式

このリリース以降、アプリケーションでは、Oracle HTTPClientでJKSキーストアのみを使用するようにする必要があります。JKSキーストアはJavaのデフォルトのキーストアであり、このキーストアを使用するためにJVMを設定する必要はありません。アプリケーションで既存のOracleウォレットのコンテンツをJKSに移行する場合は、orapkiコマンドを使用できます。

キーストアでのデータ形式の選択は、JMVで構成されているセキュリティ・プロバイダの選択に応じて異なります。デフォルトのSun Microsystemsセキュリティ・プロバイダを選択した場合は、JKS形式のキーストアを使用する必要があります。oracle.security.pkiOraclePKIProviderを選択した場合は、それをJMVで登録する必要があり、キーストア形式PKCS12またはSSO(自動ログイン)Oracleウォレットを使用する必要があります。

PKCS12およびJKSは標準キーストア形式であり、SSO Oracleウォレットは、Oracle独自の形式です。

PKCS12またはSSO形式のウォレットには、それらのすべての資格証明が暗号化されて含まれています。これらの2つのキーストアの主な違いは、SSOウォレットの場合は、ウォレットを開いてその中の情報にアクセスするためにパスワードを提示する必要がないことです。

OracleウォレットをJKSに移行するorapkiコマンドの使用方法の詳細は、Oracle Fusion Middlewareの管理者ガイドのOracleウォレットとJSKストア間での変換に関する項を参照してください。

Oracleウォレットの詳細は、Oracle Fusion Middlewareの管理者ガイドの「Oracle Wallet Managerおよびorapki」を参照してください。

20.2.2 SSL接続情報

アプリケーションでは、OracleパッケージHTTPClientのクラスHTTPConnectionのメソッドgetSSLSessionを使用して、確立したSSL接続に関する情報にアクセスできます。接続が確立されると、アプリケーションは、接続に使用される暗号スイートやピア証明連鎖などの接続情報を取得できます。

20.2.3 java.net.URLのサポート

java.net.URLフレームワークのユーザーは、http://java.sun.com/javase/6/docs/technotes/guides/security/jsse/JSSERefGuide.htmlのドキュメント(『JSSE Reference Guide』)にリストされているシステム・プロパティに従ってJSSEを構成できます。

20.2.4 暗号スイート

暗号は、暗号化および復号化を実行するアルゴリズムであり、暗号スイートはそのようなアルゴリズムのセットです。SSL接続にデータが流れる前に、接続の両端で、ネゴシエーション、およびデータ伝送に使用する一般的な暗号を含む各種接続パラメータに関するアグリーメントを行う必要があります。特定の暗号および関連するSSL接続パラメータを選択することによって、通信の参加者は、伝送チャネル上に適切なセキュリティ・レベルを確立できます。

セキュア伝送のパラメータは次のように選択することをお薦めします。

  • 鍵交換: 暗号プロトコルDiffie-Hellmanではなく、公開鍵暗号アルゴリズムRSAを選択します。

  • 対称暗号: 他の暗号化方法ではなく、トリプルDESまたはRC4 128を選択します。それらのほうがより強い鍵を使用するためです。

  • ハッシュ関数: MD5ではなくSHA1ダイジェストを使用します。SHA1のほうが、より強いダイジェストを生成するためです。

NULL暗号化が選択されている場合、SSLでは、認証およびデータの整合性チェックのみが実行されます。システム・プロパティhttps.cipherSuitesによって、使用可能な暗号スイートのサブセット(暗号スイート名のカンマ区切りリスト)が指定されます。

20.3 JSSEシステム・プロパティ

この項では、セキュリティ資格証明情報の設定に使用されるいくつかの標準JSSEシステム・キーストア・プロパティについて説明します。

javax.net.ssl.keyStore

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

javax.net.ssl.keyStorePassword

このプロパティは、キーストア(キーストアまたはウォレット・ファイル)を開くために必要なパスワードを示します。Javaシステム・プロパティでキーストア・パスワードを指定すると、環境によってはセキュリティ・リスクを招くことがあります。

このリスクを避けるために、パスワードが必要な場合は、それをクリアテキストで格納しないでください。かわりに、メソッドSystem.setPropertyを使用して、それを(HTTPConnectionを開始する前に)動的に設定し、ハンドシェイクの完了後にそれを設定解除します。ただし、サーバー上で実行されている別のアプリケーションがこのプロパティをポーリングすることによりパスワードが読み取られる可能性があるため、セキュリティ・リスクは依然として存在します。

javax.net.ssl.keyStoreType

このプロパティは、キーストアに使用するファイルのタイプを示します。OraclePKIProviderを使用する場合、この値はPKCS12またはSSOです。デフォルトのSun Microsystems JSSEの実装を使用する場合、この値はJKSにする必要があります。

javax.net.ssl.trustStore

このプロパティは、javax.net.ssl.keyStoreと同様に、トラストストアとして使用するキーストアまたはウォレット・ファイルの場所と名前を示します。

javax.net.ssl.trustStorePassword

このプロパティは、javax.net.ssl.keyStorePasswordと同様に、トラストストア・ファイル(キーストアまたはウォレット)を開くために必要なパスワードを示します。

javax.net.ssl.trustStoreType

このプロパティは、機能ではプロパティjavax.net.ssl.keyStoreTypeと同一で、トラストストアに使用されるファイルのタイプを示します。

20.4 JSSEでのHTTPClientの使用

この項は、JSSEでのOracle HTTPClientの使用方法と構成の要件について説明します。この情報は、Oracle HTTPClientをOracleウォレットとともに使用するシナリオにのみ当てはまります。

デフォルトでは、HTTPClientは、JVMで使用可能なJSSE実装を使用します。

20.4.1 JSSEを使用する場合の前提条件

JSSEでHTTPClientを使用するには、次の手順を実行します。

  • Sun Microsystems JDKバージョン1.2以降(JSSEはJDK 1.4以降の一部として組み込まれています)。

  • Oracleウォレットのサポートが必要な場合は、クラスパスにファイルoraclepki.jarを含めます。ファイルjssl-1_1.jarおよびjssl-1_2.jar(Oracle Java SSLによって使用される)は必要なくなったことに注意してください。


    注意:

    このリリース以降、アプリケーションでは、Oracle HTTPClientでJKSキーストアのみを使用するようにする必要があります。JKSキーストアはJavaのデフォルトのキーストアであり、このキーストアを使用するためにJVMを設定する必要はありません。アプリケーションで既存のOracleウォレットのコンテンツをJKSに移行する場合は、orapkiコマンドを使用できます。

  • この手順は、Oracleウォレットを使用している場合にのみ必要です。次の手順のいずれかを実行し、OraclePKIProviderをJVMに登録します。

    • ファイルjre/lib/security/java.securityを編集し、security.provider.n=oracle.security.pki.OraclePKIProviderに類似したエントリを追加します。ここでnは、適切な索引番号に置き換えます。

    • メソッドSecurity.addProvider(new OraclePKIProvider())をコールします。

20.4.2 HTTPClientの構成


注意:

デフォルトでは、HTTPClientは、SSL関連のシステム・プロパティを認識する、JVM JSSEのSSLSocketFactoryを使用します。ただし、アプリケーションでは、HTTPClient用に独自のJSSE SSLSocketFactoryを構成できます。このカスタムSSLSocketFactoryは、複数のキーストアまたはトラストストアをサポートし、SSL関連のシステム・プロパティを無視するように構成することもできます。

また、デフォルトでは、HTTPClientはJVM JSSE実装を使用します。ただし、Sun SSLプロバイダが構成されている場合は、http://java.sun.com/javase/6/docs/technotes/guides/security/jsse/JSSERefGuide.htmlで定義されたルールに基づいて、cacertsファイルがトラストストアとして使用されます。


HTTPClientを構成し、JSSEを基礎となるSSLプロバイダとして使用する手順は、次のとおりです。

  1. この手順は、JDKインフラストラクチャを使用していない場合にのみ必要です。

    Sun Microsystemsユーティリティkeytoolを使用してトラストストアを作成します。このツールの使用方法の詳細は、http://java.sun.com/javase/6/docs/technotes/tools/index.html#securityを参照してください。

    トラストストアを基礎となるSSLプロバイダに割り当てます。Sun JSSEプロバイダ用に、システム・プロパティjavax.net.ssl.trustStorejavax.net.ssl.trustStoreTypeおよびjavax.net.ssl.trustStorePasswordを設定します。システム・プロパティにパスワードを設定することはお薦めできません。また、トラストストア・タイプの中には、読取りアクセス用にパスワードを必要としないものもあります。

  2. 次のサンプル・コードに示すように、HTTPClient.HTTPConnectionのインスタンスを作成します。

    HTTPConnection conn = new HTTPConnection( "https", "my.bank.com", -1 );
    
  3. オプションで、次のサンプル・コードに示すように、connectをコールし、SSL接続を確立し、SSLセッション情報を取得します。

    conn.connect();
    SSLSession sessionInfo = conn.getSSLSession();
    

20.5 SSLホスト名の検証

SSLによって、サーバーから提示された証明連鎖が有効であり、それにクライアントによって信頼される証明書が少なくとも1つ含まれていることが確認された場合でも、悪質なサード・パーティによる偽装は防止されません。このリスクに対処するHTTPS規格では、HTTPSサーバーにそれらのホスト名に対して証明書を発行することが求められています。それにより、SSL接続を確立した後は、検証の実行はクライアント側が担当します。

Oracle HTTPClientセキュリティでは、ホスト名検証機能(インタフェースjavax.net.ssl.HostnameVerifierの実装)を使用して、SSL証明書内のホスト名が、保護されたサーバーへのアクセスに使用されるURI内のホスト名と一致していることが検証されます。HTTPClientによって、SSLセッションの確立後ただちにHostnameVerifierインスタンスが呼び出され、ホスト名の不一致が検出された場合は、例外javax.net.ssl.SSLPeerUnverifiedExceptionがスローされます。


重要:

独自のホスト名検証機能の実装を使用することも(後述のように)Oracleによって提供されるホスト名検証機能を使用することもできます。そのような実装にはすべて、引数がないコンストラクタが含まれている必要があります。

クラスHostnameVerifierの詳細は、http://java.sun.com/j2se/1.4.2/docs/api/javax/net/ssl/HostnameVerifier.htmlを参照してください。

ホスト名の検証は、次の2つの項の説明のようにシステム・プロパティまたはプログラムで使用可能になっている場合にのみ実行されます。

20.5.1 システム・プロパティを使用したホスト名検証の有効化

コードを変更することなく、ホスト名の検証を有効化するには、システム・プロパティHTTPClient.defaultHostnameVerifierを、インタフェースjavax.net.ssl.HostnameVerifierを実装するクラスの完全な名前に設定します。

20.5.2 プログラムでのホスト名検証の有効化

プログラムでのホスト名の検証を有効化するには、次のメソッドを使用します。

  • static HostnameVerifier setDefaultHostnameVerifier (HostnameVerifier myHNVerifier)

    このメソッドは、Java VM全体のすべての接続に対するホスト名検証機能を、渡されるインスタンスに設定します。このメソッドは、事前にデフォルトとして設定したホスト名検証機能(存在する場合)またはNULL(Java VMに対してホスト名検証が無効化されていた場合)を返します。

  • HostnameVerifier setHostnameVerifier (HostnameVerifier myHNVerifier)

    このメソッドは、接続に対する検証機能を、渡されるインスタンスに設定し、デフォルトの設定を上書きします。渡された引数がNULLの場合は、その接続に対するホスト名検証が無効化されます。このメソッドは、その接続に対して事前に設定したホスト名検証機能(存在する場合)またはNULL(接続に対してホスト名検証が無効化されていた場合)を返します。

20.5.3 Oracle標準ホスト名検証機能

Oracle HTTPClientセキュリティには、クラスStandardHostnameVerifierが含まれています。これは、サイトのアイデンティティを確認するための標準ホスト名一致ルールを提供するホスト名検証機能の実装です。

StandardHostnameVerifierでは、SSLセッション・ホスト名と、SSL証明連鎖の最初の証明書の識別名(DN)の一般名(CN)が比較されます。比較の際、両方の名前の一致を試みるときにワイルドカード文字を使用できます。たとえば、ワイルドカードが有効になっている場合、“*.oracle.com&rdquoと“www.oracle.com&rdquoという文字列は一致します。

StandardHostnameVerifierは、次のメソッドを公開します。

  • boolean setRecognizeWildcardCNs(boolean recognizeWildcardCNs)

    このメソッドは、比較においてワイルドカードを認識するかどうかを設定します。事前に設定された値を返します。

  • boolean isRecognizeWildcardCNs()

    このメソッドは、比較でワイルドカードを使用する場合はtrueを、それ以外の場合はfalseを返します。

  • boolean verify(java.lang.String hostname, javax.net.ssl.SSLSession sslSession)

    このメソッドは、渡されたホスト名が、渡されたセッションのサーバーの認証スキームに一致する場合はtrueを、それ以外の場合はfalseを返します。

次の行は、システム・プロパティで、デフォルトのホスト名検証機能としてOracleホスト名検証機能を設定する方法を示しています。

HTTPClient.defaultHostnameVerifier=HTTPClient.StandardHostnameVerifier;

20.5.4 追加の検証

メソッドgetSSLSessionによって返されるオブジェクト内のデータを使用することにより、追加の検証を(ホスト名検証に加えて)実行する方法は、次のとおりです。最初に、データを転送することなくサーバーへの接続を確立します。

httpsConnection.connect();

次に、セッション情報を取得します。

SSLSession sessionInfo = httpsConnection.getSSLSession();

オブジェクトSSLSessionは、接続の検証に使用できる、SSL接続の多数の属性を公開します。詳細は、http://java.sun.com/j2se/1.5.0/docs/api/javax/net/ssl/SSLSession.htmlを参照してください。

20.6 Oracle HTTPClientでのNTLM認証の使用方法

NT LAN Manager(NTLM)は、クライアント、プロキシ、およびサーバーで使用できる、Oracle HTTPClientによってサポートされているMicrosoft認証プロトコルです。

NTLMは、接続指向のプロトコルです。接続が認証された後は、接続がオープンになっているかぎり、伝送のための追加の資格証明は必要ありません。したがって、NTLMを使用するクライアントは、そのアイデンティティを証明して接続を確立したら、その後、パスワードを送信する必要はありません。

プロキシ・サーバーでは、クライアント認証のためにもNTLMを使用できます。ただし、いくつかのリクエスト指向の認証スキーム(Basic認証やDigest認証など)とは異なり、NTLMクライアントは、プロキシ・サーバーとの接続のみを認証し、リソース・サーバーとの接続は認証しません。

HTTPClientは、基本認証およびダイジェスト認証もサポートしています。このサポートは、HTTPClientのオープン・ソース・バージョンで提供されているものと同じです。

20.6.1 NTLMドメイン名とレルム

NTLMアカウント識別子は、NTDname\userNameという形式です。ここでオプションの文字列NTDnameは、NTドメイン名を識別します。存在しない場合は、デフォルトのNTドメイン名が想定されます。デフォルトのNTドメイン名は、システム・プロパティHTTPClient.ntlm.defaultDomainNameで設定されます。さらに、アカウント識別子にNTドメイン名が含まれてなく、デフォルトも設定されていない場合、NTLMで保護されたサーバーでは独自のNTドメイン名が使用されます。

レルムは、いくつかの認証スキーム(Basic認証など)で指定されます。NTLMでは、チャレンジにレルム・ディレクティブが含まれていないため、レルムは適用されません。したがって、すべてのNTLM資格証明は、HTTPClient接続内の同じ空のレルムの一部と想定されます。

20.6.2 NTLM保護されたサーバーへの接続

NTLM保護されたリソースまたはプロキシ・サーバーに接続するには、資格証明をHTTPClient AuthorizationInfo資格証明ストアに追加する必要があります。これは、クライアントの接続先のサーバーのタイプに応じて2つの方法のいずれかで実行されます。どの場合も、NTLMサーバーから要求されると、HTTPClientによって自動的に資格証明ストアへの問合せが行われます。

NTLM保護されたリソース・サーバーに接続するには、次のコードSnippetに示すようにHTTPConnectionインスタンスを使用してNTLM資格証明を追加します。

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

前述の例では、myHostで表されるリソース・サーバーのNTLM資格証明を追加していることに注意してください。

もう1つの方法としては、次のコードSnippetに示すように、オブジェクトAuthorizationInfoを使用してNTLM資格証明を直接追加します。

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 );

前述の例では、myProxyHostで表されるプロキシ・サーバーのNTLM資格証明を追加していることに注意してください。

NTLM保護されたプロキシ・サーバーに接続するには、前述のようにHTTPConnection.addNtlmAuthenticationを使用して直接NTLM資格証明を追加します。これは、メソッドaddNtlmAuthenticationでは、プロキシ・サーバーではなく関連するリソース・サーバーの資格証明が追加されるためです。