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
を参照してください。
Oracle HTTPClientセキュリティは、パッケージHTTPClient.HTTPConnection
を実装し、ソースとターゲット間のHTTP接続(セキュアな接続またはそれ以外の接続)の作成を可能にする関数の包括的なセットを提供します。クラスHTTPClient
のOracleによる実装は、そのベースであるオリジナルのオープン・ソース・バージョンとは異なります。それらの間には多数の類似点がありますが、この2つの実装は必ずしも互換ではありません。
JSSEおよびjava.net
の詳細は、次のリンクの情報を参照してください。
Oracle HTTPSクライアントによってセキュリティ認識アプリケーションに提供される主な機能は、次のとおりです。
JKSおよびPKCS12(Oracleウォレット)キーストアのサポート。ただし、このリリース以降、HTTPClientで使用するキーストアとしてJKSキーストアが優先されます。HTTPClientでのOracleウォレットの使用はすべて、JKS使用に切り替える必要があります。
プロキシを介したHTTPSトンネリング
HTTPプロキシ認証
(制限付き)java.net.URL
フレームワークのサポート
Oracle HTTPClientでは、クライアントとサーバー間の通信に対するプロトコルHTTP 1.0およびHTTP 1.1の使用、およびJSSE SSLの実装がサポートされています。OraclePKIProviderをJVMに追加しないとOracleウォレットは使用できないことに注意してください。「JSSEを使用する場合の前提条件」を参照してください。
次の4つの項で、Oracle HTTPClientセキュリティによってサポートされる主要な機能について詳しく説明します。
このリリース以降、アプリケーションでは、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」を参照してください。
アプリケーションでは、OracleパッケージHTTPClient
のクラスHTTPConnection
のメソッドgetSSLSession
を使用して、確立したSSL接続に関する情報にアクセスできます。接続が確立されると、アプリケーションは、接続に使用される暗号スイートやピア証明連鎖などの接続情報を取得できます。
java.net.URL
フレームワークのユーザーは、http://java.sun.com/javase/6/docs/technotes/guides/security/jsse/JSSERefGuide.html
のドキュメント(『JSSE Reference Guide』)にリストされているシステム・プロパティに従ってJSSEを構成できます。
暗号は、暗号化および復号化を実行するアルゴリズムであり、暗号スイートはそのようなアルゴリズムのセットです。SSL接続にデータが流れる前に、接続の両端で、ネゴシエーション、およびデータ伝送に使用する一般的な暗号を含む各種接続パラメータに関するアグリーメントを行う必要があります。特定の暗号および関連するSSL接続パラメータを選択することによって、通信の参加者は、伝送チャネル上に適切なセキュリティ・レベルを確立できます。
セキュア伝送のパラメータは次のように選択することをお薦めします。
対称暗号: 他の暗号化方法ではなく、トリプルDESまたはRC4 128を選択します。それらのほうがより強い鍵を使用するためです。
ハッシュ関数: MD5ではなくSHA1ダイジェストを使用します。SHA1のほうが、より強いダイジェストを生成するためです。
NULL暗号化が選択されている場合、SSLでは、認証およびデータの整合性チェックのみが実行されます。システム・プロパティhttps.cipherSuites
によって、使用可能な暗号スイートのサブセット(暗号スイート名のカンマ区切りリスト)が指定されます。
この項では、セキュリティ資格証明情報の設定に使用されるいくつかの標準JSSEシステム・キーストア・プロパティについて説明します。
このプロパティは、キーストアとして使用するキーストアまたはウォレット・ファイルの場所と名前を示します。
javax.net.ssl.keyStorePassword
このプロパティは、キーストア(キーストアまたはウォレット・ファイル)を開くために必要なパスワードを示します。Javaシステム・プロパティでキーストア・パスワードを指定すると、環境によってはセキュリティ・リスクを招くことがあります。
このリスクを避けるために、パスワードが必要な場合は、それをクリアテキストで格納しないでください。かわりに、メソッドSystem.setProperty
を使用して、それを(HTTPConnection
を開始する前に)動的に設定し、ハンドシェイクの完了後にそれを設定解除します。ただし、サーバー上で実行されている別のアプリケーションがこのプロパティをポーリングすることによりパスワードが読み取られる可能性があるため、セキュリティ・リスクは依然として存在します。
このプロパティは、キーストアに使用するファイルのタイプを示します。OraclePKIProviderを使用する場合、この値はPKCS12またはSSOです。デフォルトのSun Microsystems JSSEの実装を使用する場合、この値はJKSにする必要があります。
このプロパティは、javax.net.ssl.keyStore
と同様に、トラストストアとして使用するキーストアまたはウォレット・ファイルの場所と名前を示します。
javax.net.ssl.trustStorePassword
このプロパティは、javax.net.ssl.keyStorePassword
と同様に、トラストストア・ファイル(キーストアまたはウォレット)を開くために必要なパスワードを示します。
このプロパティは、機能ではプロパティjavax.net.ssl.keyStoreType
と同一で、トラストストアに使用されるファイルのタイプを示します。
この項は、JSSEでのOracle HTTPClientの使用方法と構成の要件について説明します。この情報は、Oracle HTTPClientをOracleウォレットとともに使用するシナリオにのみ当てはまります。
デフォルトでは、HTTPClientは、JVMで使用可能な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ウォレットを使用している場合にのみ必要です。次の手順のいずれかを実行し、OraclePKIProviderをJVMに登録します。
ファイルjre/lib/security/java.security
を編集し、security.provider.n=oracle.security.pki.OraclePKIProvider
に類似したエントリを追加します。ここでn
は、適切な索引番号に置き換えます。
メソッドSecurity.addProvider(new OraclePKIProvider())
をコールします。
注意: デフォルトでは、HTTPClient は、SSL関連のシステム・プロパティを認識する、JVM JSSEのSSLSocketFactory を使用します。ただし、アプリケーションでは、HTTPClient用に独自のJSSE SSLSocketFactory を構成できます。このカスタムSSLSocketFactory は、複数のキーストアまたはトラストストアをサポートし、SSL関連のシステム・プロパティを無視するように構成することもできます。
また、デフォルトでは、 |
HTTPClient
を構成し、JSSEを基礎となるSSLプロバイダとして使用する手順は、次のとおりです。
この手順は、JDKインフラストラクチャを使用していない場合にのみ必要です。
Sun Microsystemsユーティリティkeytool
を使用してトラストストアを作成します。このツールの使用方法の詳細は、http://java.sun.com/javase/6/docs/technotes/tools/index.html#security
を参照してください。
トラストストアを基礎となるSSLプロバイダに割り当てます。Sun JSSEプロバイダ用に、システム・プロパティjavax.net.ssl.trustStore
、javax.net.ssl.trustStoreType
およびjavax.net.ssl.trustStorePassword
を設定します。システム・プロパティにパスワードを設定することはお薦めできません。また、トラストストア・タイプの中には、読取りアクセス用にパスワードを必要としないものもあります。
次のサンプル・コードに示すように、HTTPClient.HTTPConnection
のインスタンスを作成します。
HTTPConnection conn = new HTTPConnection( "https", "my.bank.com", -1 );
オプションで、次のサンプル・コードに示すように、connect
をコールし、SSL接続を確立し、SSLセッション情報を取得します。
conn.connect(); SSLSession sessionInfo = conn.getSSLSession();
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つの項の説明のようにシステム・プロパティまたはプログラムで使用可能になっている場合にのみ実行されます。
コードを変更することなく、ホスト名の検証を有効化するには、システム・プロパティHTTPClient.defaultHostnameVerifier
を、インタフェースjavax.net.ssl.HostnameVerifier
を実装するクラスの完全な名前に設定します。
プログラムでのホスト名の検証を有効化するには、次のメソッドを使用します。
static HostnameVerifier setDefaultHostnameVerifier (HostnameVerifier myHNVerifier)
このメソッドは、Java VM全体のすべての接続に対するホスト名検証機能を、渡されるインスタンスに設定します。このメソッドは、事前にデフォルトとして設定したホスト名検証機能(存在する場合)またはNULL(Java VMに対してホスト名検証が無効化されていた場合)を返します。
HostnameVerifier setHostnameVerifier (HostnameVerifier myHNVerifier)
このメソッドは、接続に対する検証機能を、渡されるインスタンスに設定し、デフォルトの設定を上書きします。渡された引数がNULLの場合は、その接続に対するホスト名検証が無効化されます。このメソッドは、その接続に対して事前に設定したホスト名検証機能(存在する場合)またはNULL(接続に対してホスト名検証が無効化されていた場合)を返します。
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;
メソッドgetSSLSession
によって返されるオブジェクト内のデータを使用することにより、追加の検証を(ホスト名検証に加えて)実行する方法は、次のとおりです。最初に、データを転送することなくサーバーへの接続を確立します。
httpsConnection.connect();
次に、セッション情報を取得します。
SSLSession sessionInfo = httpsConnection.getSSLSession();
オブジェクトSSLSession
は、接続の検証に使用できる、SSL接続の多数の属性を公開します。詳細は、http://java.sun.com/j2se/1.5.0/docs/api/javax/net/ssl/SSLSession.html
を参照してください。
NT LAN Manager(NTLM)は、クライアント、プロキシ、およびサーバーで使用できる、Oracle HTTPClientによってサポートされているMicrosoft認証プロトコルです。
NTLMは、接続指向のプロトコルです。接続が認証された後は、接続がオープンになっているかぎり、伝送のための追加の資格証明は必要ありません。したがって、NTLMを使用するクライアントは、そのアイデンティティを証明して接続を確立したら、その後、パスワードを送信する必要はありません。
プロキシ・サーバーでは、クライアント認証のためにもNTLMを使用できます。ただし、いくつかのリクエスト指向の認証スキーム(Basic認証やDigest認証など)とは異なり、NTLMクライアントは、プロキシ・サーバーとの接続のみを認証し、リソース・サーバーとの接続は認証しません。
HTTPClientは、基本認証およびダイジェスト認証もサポートしています。このサポートは、HTTPClientのオープン・ソース・バージョンで提供されているものと同じです。
NTLMアカウント識別子は、NTDname\userName
という形式です。ここでオプションの文字列NTDname
は、NTドメイン名を識別します。存在しない場合は、デフォルトのNTドメイン名が想定されます。デフォルトのNTドメイン名は、システム・プロパティHTTPClient.ntlm.defaultDomainName
で設定されます。さらに、アカウント識別子にNTドメイン名が含まれてなく、デフォルトも設定されていない場合、NTLMで保護されたサーバーでは独自のNTドメイン名が使用されます。
レルムは、いくつかの認証スキーム(Basic認証など)で指定されます。NTLMでは、チャレンジにレルム・ディレクティブが含まれていないため、レルムは適用されません。したがって、すべてのNTLM資格証明は、HTTPClient接続内の同じ空のレルムの一部と想定されます。
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
では、プロキシ・サーバーではなく関連するリソース・サーバーの資格証明が追加されるためです。