Oracle Containers for J2EE
セキュリティ・ガイド
10g(10.1.3.4.0) B50832-01 |
|
この章では、クライアントのOracleセキュリティの機能について説明します。この機能は、主に、クライアントHTTP接続にSecure Sockets Layer(SSL)機能とHTTPClient
パッケージの機能を提供し、標準的なJava Secure Socket Extension(JSSE)の使用をサポートします。また、HTTPクライアントの非SSL認証機能を説明する項が含まれています。この章では、OC4JがWebリスナー(スタンドアロンのOC4Jなど)であるか、OC4JがOracle HTTP Serverの背後にある状況で、SSLを使用するJavaアプリケーションについて説明します。
この章の内容は次のとおりです。
注意
HTTPClient
の場合、JSSEがデフォルトのSSL実装になっています。Oracle Java SSLについての最後の項を除き、この章ではJSSEの使用方法を中心に説明します。
この章では、主にクライアント・セキュリティ用HTTPSについて説明しています。ただし、一部のHTTPクライアントAPIは、非SSL認証用にクライアントで使用できます。ライブラリを使用して、リクエスト・ヘッダーにBasic、DigestおよびNTLMの認証情報を含めるHTTPリクエストを作成できます。この項では、HTTPClient
パッケージを使用してこれらのタイプのリクエストを作成する方法を説明します。HTTPクライアントAPIの詳細は、『Oracle Application Server HTTPClient Java API Reference』を参照してください。
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をグループ化するサーバー指定文字列であり、サーバーによって認証チャレンジが発行された場合に正しい情報を選択するために使用されます。レルムを使用しないスキームでは、レルムを空の文字列(""
)にする必要があります。
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は、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 );
プロキシ・サーバーでも、クライアント認証に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はWebサーバーにより処理されます。ただし、他のWebサーバーへの接続を開始するWebアプリケーションなど、クライアントとして機能するアプリケーションには、サーバーとの間で情報をセキュアにやり取りするために独自のHTTPS実装が必要です。HTTPClient
パッケージまたはSun社のjava.net
パッケージに精通しているJavaアプリケーション開発者は、HTTPSを使用してクライアントとサーバーとの対話を簡単に保護できます。
OracleクライアントHTTPS機能は、完全なHTTPクライアント・ライブラリを提供する、HTTPClient
パッケージのHTTPConnection
クラスをベースにしています。HTTPConnection
クラスは、SSLを使用するかどうかを問わず、HTTPを使用する新規接続の作成に使用されます。
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独自の形式です。
Oracle HTTPClient
パッケージのHTTPConnection
クラスにあるgetSSLSession()
メソッドを使用すると、確立されたSSL接続に関する情報にアクセスできます。接続の確立後は、接続に使用された暗号スイート、ピア証明連鎖および現行の接続に関するその他の情報を取得できます。
HTTPClient
パッケージは、HTTPClient.HttpUrlConnection
クラスによりjava.net.URL
フレームワークの基本サポートを提供します。ただし、OracleクライアントHTTPSの機能の多くは、システム・プロパティを介してのみサポートされます。
システム・プロパティを介してのみサポートされる機能は、次のとおりです。
データがSSL接続を介して流れる前に、接続の両端がデータ送信に使用する共通アルゴリズムを折衝する必要があります。混在型のセキュリティ機能を提供するために結合されているアルゴリズムのセットは、暗号スイートと呼ばれます。SSL接続の参加者は、特定の暗号スイートを選択すると適切な通信レベルを確立できます。
通常は、次の優先順位に従う必要があります。
OC4J 10.1.3.1リリースでJSSEがサポートする暗号スイートを、デフォルトの優先順序で次に示します。このリストで、"*"が付いたスイートは、デフォルトで有効になる暗号スイートを表し、"**"が付いたスイートは、Sun社のJCE Unlimited Strength Jurisdiction Policy Filesのインストールが必要な暗号スイートを表しています。NULL暗号化の場合、SSLは認証とデータ整合性のためにのみ使用されることに注意してください。
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
この項では、キーストアとトラストストアに対してサポートされる標準のJavaシステム・プロパティについて説明します。(java.net.URL
フレームワークのユーザーがセキュリティ資格証明情報を設定するには、これらのプロパティを使用する必要があります。)OracleクライアントHTTPSでは、次のプロパティが認識されます。
このプロパティは、キーストアとして使用するキーストア・ファイルまたはWalletファイルの場所と名前を指定します。
このプロパティは、キーストア(キーストア・ファイルまたはWalletファイル)を開くために必要なパスワードを指定できます。次に例を示します。
javax.net.ssl.keyStorePassword=welcome1
このプロパティは、キーストアで使用されるファイルのタイプを指定します。Oracle JSSE実装(OraclePKIProvider
)の場合、PKCS12
またはSSO
を指定できます。デフォルトのSun社のJSSE実装の場合、JKS
を指定できます。
このプロパティは、javax.net.ssl.keyStore
と同様に使用されます。このプロパティは、トラストストア(クライアントが暗黙的に受け入れる信頼できる認証局を格納するファイル)として使用するキーストア・ファイルまたはWalletファイルの場所と名前を指定します。
このプロパティは、javax.net.ssl.keyStorePassword
と同様に使用されます。このプロパティは、トラストストア(キーストア・ファイルまたはWalletファイル)を開くために必要なパスワードを指定します。
javax.net.ssl.keyStoreType
と同様に、このプロパティは、トラストストアで使用するファイル・タイプを指定します。Oracle JSSE実装の場合はPKCS12
またはSSO
で、Sun社のJSSE実装のデフォルトの場合はJKS
です。
この項では、JSSEを使用するHTTPSクライアント接続のOracle Application Serverサポートについて説明します。この項の内容は次のとおりです。
OracleクライアントHTTPSでJSSEを使用する場合、次の要件があります。
ORACLE_HOME
/network/jlib
にあるファイルoraclepki.jar
が、クラスパス内に存在する必要があります。(Oracle Java SSLで使用するファイルjssl-1_1.jar
またはjssl-1_2.jar
は、必要なくなりました。これらのファイルはJSSEと互換性がないため、インストール環境に含まれていません。)
Oracle Application Serverは、JSSEを使用してHTTPSクライアント接続をサポートします。クライアントでは、次の手順に従い、基礎となるSSLプロバイダとしてJSSEを使用するようにHTTPClient
を構成できます。
keytool
を使用してトラストストアを作成します。 javax.net.ssl.trustStore
プロパティを介してクライアント・トラストストアの位置を指定する必要があります。クライアントでjavax.net.ssl.keyStore
プロパティを設定する必要はありません。
SSLSocketFactory.getDefault()
をコールして、JSSE SSLソケット・ファクトリ(javax.net.ssl.SSLSocketFactory
インスタンス)を取得します。
HTTPClient
接続(HTTPConnection
インスタンス)を作成します。
HTTPClient
接続を構成します。JSSEを使用するようにHTTPClient
を構成するには、次のいずれかの方法があります。
HTTPConnection
インスタンスの次のメソッドをコールします。その際、手順3のgetDefault()
メソッドにより取得されたJSSE SSLソケット・ファクトリを指定します。
void setSSLSocketFactory(SSLSocketFactory factory)
この場合、SSLソケット・ファクトリはこの接続インスタンス用にのみ設定されます。その技術的方法については、後出の例16-1に示されています。
HTTPConnection
クラスの次の静的メソッドをコールします。
void HttpConnection.setDefaultSSLSocketFactory(SSLSocketFactory factory)
この場合、メソッドを別の設定で再コールしないかぎり、SSLソケット・ファクトリがJava VM内のすべての接続インスタンスに対して設定されます。このメソッドは、対象となるHTTPConnection
インスタンスをインスタンス化する前にコールする必要があります。
HTTPConnection
クラスのconnect()
メソッドを呼び出す必要があります。これにより、接続では、データを暗号化して送信する前に、クライアントとサーバー間に発生する必要のあるSSLハンドシェイキングを検証できます。Oracle実装の場合、HTTPConnection
クラスのGet()
メソッドなど、HTTPメソッドの呼び出し時にこのメソッドが暗黙的に呼び出されます。また、データ送信の前にコール元アプリケーションがSSLセッション情報を必要とする場合、connect()
メソッドを明示的に呼び出すと便利です。「追加の接続情報の検証」を参照してください。
HTTPConnection
インスタンスを通常の方法で使用します。この時点で、クライアントはJSSEとともにHTTPClient
を使用するように設定されています。追加構成は不要であり、基本的な使用方法は同じです。 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では、サーバーから提示された証明連鎖が有効で、クライアントが信頼できる証明書が1つ以上含まれているかどうかが検証されますが、悪意のある第三者による偽装は防止されません。この問題に対処するHTTPS規格は、HTTPSサーバーがそのホスト名に対して発行された証明書を持つように求めています。このため、クライアントはSSL接続の確立後に、この検証を実行する必要があります。
ホスト名検証機能(javax.net.ssl.HostnameVerifier
implementation)は、HTTPClient
によって使用されます。これにより、保護されているサーバーへアクセスする際に使用されるURIのホスト名と、SSL証明書のホスト名が一致するかどうかが検証されます。これは、介入者攻撃の検出に役立ちます。HTTPClient
は、SSLセッションを確立した直後にHostnameVerifier
インスタンスを呼び出し、ホスト名の不一致が検出された場合はjavax.net.ssl.SSLPeerUnverifiedException
をスローします。
この項では、この機能を有効にして使用する方法を説明します。この項の内容は次のとおりです。
ホスト名検証を実行するには、次に説明するシステム・プロパティ設定またはプログラム設定が必要です。
コードを変更することなくホスト名検証を有効にするには、システム・プロパティHTTPClient.defaultHostnameVerifier
に、クラスパス内にあるホスト名検証機能実装の完全修飾されたクラス名を設定します。
設定する場合、適切なクラスの名前(引数なしのコンストラクタ付きのjavax.net.ssl.HostnameVerifier
実装)を指定する必要があります。
検証に使用するjavax.net.ssl.HostnameVerifier
インスタンスを指定することにより、次に示すHTTPConnection
クラスのメソッドを使用して、ホスト名検証をプログラムによって有効にすることができます。
static HostnameVerifier setDefaultHostnameVerifier
(HostnameVerifier defaultHostnameVerifier)
この静的メソッドを使用して、指定されたHostnameVerifier
インスタンスをJVMのデフォルトとして割り当てます。このメソッドは、以前に設定したデフォルトのホスト名検証機能を返します。ホスト名検証が以前にデフォルトで無効にされている場合は、null
を返します。
HostnameVerifier setHostnameVerifier
(HostnameVerifier hostnameVerifier)
接続で使用するため、このインスタンス・メソッドを使用してデフォルトのホスト名検証機能をオーバーライドし、指定されたHostnameVerifier
インスタンスを割り当てます。null
を指定して、接続のホスト名検証を無効にすることもできます。
このメソッドは、接続用の前のホスト名検証機能を返します。接続のホスト名検証があらかじめ無効にされている場合は、null
を返します。
HTTPClient
パッケージ内に、ホスト名検証機能の実装のStandardHostnameVerifier
が用意されています。
StandardHostnameVerifier
は、サイトのアイデンティティをチェックする標準的なホスト名一致規則を実装し、次の機能を備えています。
*.oracle.com
などのSSL証明書のワイルドカードCNと比較されます(存在する場合)。
StandardHostnameVerifier
には、次のメソッドがあります。
boolean setRecognizeWildcardCNs(boolean recognizeWildcardCNs)
ワイルドカードCNを認識するかどうかを指定します。このメソッドは、前に設定された値を返します。
boolean isRecognizeWildcardCNs()
このメソッドは、ワイルドカードCNが認識されるかどうかを通知します。
boolean verify(java.lang.String hostname, javax.net.ssl.SSLSession sslSession)
このメソッドを呼び出し、ホスト名がサーバーの認証スキームと許容できる範囲で一致するかどうかを検証します。(これは、javax.net.ssl.HostnameVerifier
インタフェースに指定された標準機能です。)
前述のように、プログラムまたはシステム・プロパティ設定により、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); }
前述のように、OC4J 10.1.3.1以降の実装の場合、Oracle Java SSLではなくJSSEを使用することをお薦めします。Oracle Java SSLは10.1.3.1実装で非推奨であり、将来のリリースでサポートされなくなります。この項では、SSL機能に対してOracle Java SSLのかわりにJSSEを使用するようクライアント・コードを変更する方法を説明します。
この項では、JSSEを使用する新しいSSLソケット・ファクトリを作成する手順を示すため、以前にOracle Java SSLで使用していたものと同じコードと比較しながら、コード・サンプルを説明します。java.security.Keystore
クラスと様々なjavax.net.ssl
クラスは、ピア証明の検証用にキーストアまたはWalletを開き、Oracle固有のセキュリティ・ポリシーを適用する場合に使用されます。
次に、説明と比較を加えながら手順を説明します。
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クラスを使用できます。
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では使用しません。
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ソケットを作成する際に使用できます。
次に示す追加の変更をOracle Java SSLとJSSEの間で行うと、アプリケーションに影響する場合があります。
createSocket()
メソッドの署名が異なる場合。(これは、Oracle Java SSLの場合はOracleSSLSocketFactory
インスタンス、JSSEの場合はSSLSocketFactory
インスタンスです。)ただし、createSocket()
を直接呼び出す場合、HTTPClient
のユーザーは必要ありません。Oracle Java SSL用の従来の署名:
createSocket(Socket sock)
JSSE用の新しい署名:
createSocket(Socket sock, String host, int port, boolean autoClose)
このメソッドは、既存のソケットの上に新しいソケットを作成します。既存のソケット、サーバーのホスト、サーバーのポートを指定し、作成されたソケットを閉じる際に下位のソケットを閉じるかどうかを指定します。
Oracle Java SSLの場合、OracleSSLSession
のgetPeerCertificateChain()
メソッドは、ルートCA証明書が最初でピア証明が最後になった証明連鎖を返します。
JSSEの場合、SSLSession
のgetPeerCertificates()
メソッド(推奨)またはgetPeerCertificateChain()
メソッド(下位互換性のために維持)は、ピア証明が最初でルートCA証明書が最後になった証明連鎖を返します。
Oracle Java SSLは、OC4J 10.1.3.1実装では非推奨ですが、サポートはされています。(将来のリリースではサポートされなくなる予定です。)
この項ではOracle Java SSL固有の機能について記載していますが、「Oracle Java SSLからJSSEへの移行」で説明しているように、JSSEへの移行をお薦めします。
この項の内容は次のとおりです。
OC4J 10.1.3.1実装の場合、JDKのデフォルトのJSSE実装が、HTTPClient
のデフォルトのSSL実装になりました。(これにより、HTTPClient
の以前のデフォルトSSL実装であったOracle Java SSLは、今後非推奨となります。)
ただし、次の手順を実行すると、Oracle Java SSLをHTTPClient
のデフォルトSSL実装として明示的に指定することができます。
HTTPClient.preferOracleSSL=true
oracle.security.ssl.OracleSSLSocketFactory
など)内にあることを確認します。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クライアントHTTPSでは、SSLを使用してセキュリティ対応アプリケーションのサポート機能が提供されます。セキュリティ対応アプリケーションでトラスト・ポイントが設定されていない場合は、SSLを使用すると、独自の検証を実行して、ピアから完全な証明連鎖が送信された場合にのみハンドシェイクを正常終了させることができます。アプリケーションでトラスト・ポイント・レベルまで認証する場合は、トラスト・ポイントの下の個々の証明書を認証する必要があります。
ハンドシェイクの完了後に、アプリケーションはSSLセッション情報を取得して、接続について追加の検証を実行する必要があります。
トラスト・ポイントのチェックを必要とするセキュリティ非対応アプリケーションでは、HTTPSのインフラストラクチャ内でトラスト・ポイントが設定されていることを確認する必要があります。
この項では、HTTPClient
およびOracle Java SSLを使用してWebサーバーに接続し、GET
リクエストを送信してWebページをフェッチするアプリケーションを示します。
この項では、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 Wallet Managerにより作成されたWalletを使用して資格証明情報を設定します。
mycredential = new OracleSSLCredential(); mycredential.setWallet(wallet_path, password);
HTTPConnection
インスタンス(ここでの名前はhttpsConnection
)に、インスタンスのメソッドsetSSLCredential()
を介して渡されます。このメソッドは、次のように、最初の手順で作成されたOracleSSLCredential
インスタンスを入力として取ります。
httpsConnection.setSSLCredential(mycredential);
これにより、Walletに置かれた秘密鍵、ユーザー証明書およびトラスト・ポイントを接続に使用できます。
「サポートされているデフォルトのシステム・プロパティ」では、Javaシステム・プロパティのkeyStore
、keyStorePassword
、keyStoreType
、trustStore
、trustStorePassword
、trustStoreType
について説明しています。この項では、Oracle Java SSL固有のjavax.net.ssl.keyStore
に関連する次の機能を説明します。
IOException
がスローされます。
この項では、Oracle Java SSLの暗号スイートを指定する方法について説明します。
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接続で有効な暗号スイートとして使用されます。
Oracle Java SSLの場合、パッケージHTTPClient
のHTTPConnection
クラスの次のメソッドを使用することにより、接続ごとに暗号スイートを設定することもできます。
これは、各配列要素で暗号スイートを指定するJava文字列配列を取ります。現在のSSL実装がこのメソッドをサポートするかどうかを示すブール値を返します。
Oracle Java SSLは、表16-1に示す暗号スイートをサポートします。NULL暗号化の場合、SSLは認証とデータ整合性のためにのみ使用されることに注意してください。
|
Copyright © 2003, 2008 Oracle Corporation. All Rights Reserved. |
|