2013-08-14 24 views
5

HTTPSを使用していくつかのサーバーと通信する必要があるアプリケーションを作成しています。 AWSと(AWSライブラリを使用して)やTLS 1.2を使用する内部サービスの一部と通信する必要があります。複数のTLSプロトコルをサポートするHttpClient

私はTLS 1.2のSSLContextを使用するために私のHttpClientを変更することで始まっ:

public static SchemeRegistry buildSchemeRegistry() throws Exception { 
    final SSLContext sslContext = SSLContext.getInstance("TLSv1.2"); 
    sslContext.init(createKeyManager(), createTrustManager(), new SecureRandom()); 
    final SchemeRegistry schemeRegistry = new SchemeRegistry(); 
    schemeRegistry.register(new Scheme("https", 443, new SSLSocketFactory(sslContext))); 
    return schemeRegistry; 
} 

と(春経由)DefaultHttpClientオブジェクトにこのSchemeRegistryを注入し、私はAWSからエラーが出るので、私が想定していることやって私は春に定義された2つのHttpClientsを持ってしようとした場合、1を

AmazonServiceException: Status Code: 403, AWS Service: AmazonSimpleDB, AWS Request ID: 5d91d65f-7158-91b6-431d-56e1c76a844c, AWS Error Code: InvalidClientTokenId, AWS Error Message: The AWS Access Key Id you provided does not exist in our records. 

:AWSは、TLS 1.2を(私は通常のDefaultHttpClientを使用している場合、私はこのメッセージを得ることはありません)をサポートしていないこと(私が間違っている可能性があります)それはTLS 1.2とデフォルトを使用するものを使用しています私が想定し、エラーを起因と、春は以下のように2つのHttpClientオブジェクトをインスタンス化し、オートワイヤリングしないことを意味します

SEVERE: Servlet /my-refsvc threw load() exception 
java.lang.NullPointerException 
at com.company.project.refsvc.base.HttpsClientFactory.<clinit>(BentoHttpsClientFactory.java:25) 
... 
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1031) 
at 
... 
org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:223) 

私はJavaでHTTPSをあまり使用していないので、あなたの種類の人々が私にいくつかのアドバイスをしてくださいお願いしますか。 1)Springに2つのHttpClientオブジェクトを許可し、AWS stuff beansに配線する方法と、もう一方をTLS1.2サービスにアクセスするために他のBeanに配線する方法を教えてください。 2)または変更可能です1つのHttpClientオブジェクトがTLS1.2を(SSLContextまたはSchemeRegistryなどを介して)試すことができ、それが失敗した場合はTLS1.1または1.0を試してみてください。 3)どちらも可能な場合、それを行う「より良い」方法は何でしょうか?

+0

のためにそれを有効にする方法について小さなブログの記事を作成し、あなたが '' SSLContext.getInstance(「TLSv1.1」)を使用した場合、同じエラーが出る 'またはでくださいSSLContext.getInstance( "TLS") '? – Bruno

+0

はい、同じエラーが表示されます。私はそれがTLSバージョンではなく、それを台無しにしている私のクライアント側の証明書かどうか疑問に思っています。 – agentgonzo

+0

(SSLContext sslContext = SSLContext.getDefault() 'が既に初期化されている場合)にデフォルトの' SSLContext'を使うようにしてください。それ以外の場合は、カスタム化を減らしてください。 'sslContext.init(createKeyManager()、null、null)'は、TMとSecureRandomのデフォルトを使用する必要があります。 keymanagerにはデフォルトがないので、keymanagerコードに何か問題がある可能性があります(サーバーがクライアント証明書を要求している場合にのみ便利です)。 – Bruno

答えて

3

TLSには、使用するプロトコルのバージョンをネゴシエートする組み込みのメカニズムがあります。 RFC 5246 (Appendix E)から:

TLSバージョン1.0、1.1、および1.2、およびSSL 3.0は非常に似ており、 使用互換性のClientHelloメッセージ。したがって、それらのすべてをサポートするのは、比較的簡単です です。同様に、サーバは、ClientHello フォーマットが互換性を保ち、クライアントがサーバで利用可能な最高の プロトコルバージョンをサポートしている限り、TLSの将来のバージョンを使用しようとするクライアント を容易に処理できます。

A TLS はClientHello.client_versionに{3,3}(TLS 1.2)を含有する、通常TLS 1.2のClientHelloを送信するよう古いサーバと交渉することを望む1.2クライアント。サーバーがこのバージョンをサポートしていない場合、古いバージョン番号 を含むServerHelloで応答します。クライアントがこのバージョンを使用することに同意する場合、 ネゴシエーションは交渉された プロトコルに応じて適切に進められます。プロトコルはデフォルトでを有効にしているSSLContext.getInstance(...)変更のみで、バージョン番号を変更することに加えて

、。実際のプロトコルバージョンの設定は、SSLSocket.setEnabledProtocols(...)this questionを参照)で行います。残りのライブラリについてはわかりませんが、有効なプロトコルをどこかに設定する可能性があります。あなたはcreateKeyManager()でやっている

  • デフォルトの動作とは異なります

    は、いくつかの可能性があります。サービスがクライアント証明書認証を使用している場合、構成が正しくなければ、403エラーが発生します。

  • (これはあまりありませんが、あなたのcreateKeyManager()createTrustManager()を見ずには言い難いです)。使用しているサーバーが、TLS 1.2およびバージョンネゴシエーションメカニズムと互換性がない可能性があります。 sun.security.ssl.SSLContextImplでこのコメントがあります:

    SSL/TLSプロトコルは、前方互換性とバージョン ロールバックアタックの保護を指定して、しかし、SSL/TLSサーバーの数が ベンダーが適切にこれらの側面を実装し、いくつかしていませんcurrent SSL/TLSサーバーは、TLS 1.1以降のクライアントとの通信を拒否することがあります。

+0

私たちはクライアント証明書認証を使用していますが、クライアント証明書を使用してAWSサーバーで認証しようとしているときに、エラーが発生しないかどうかはわかりません。 AWSは認証にHMAC署名を使用していますが、私が実際には分かっていない以上のものです。 createKeyManagerとcreateTrustManagerは、.jksファイルをロードしてオブジェクトを返します(このコメントにコードを投稿できません)。 – agentgonzo

+0

@agentgonzo、より多くのコードを投稿したい場合は、あなたの質問を編集できます。アプリケーション(デフォルト)は、キーストア(javax.net.ssl。*プロパティ)の他の設定を使用しようとしますか?他のコンテキスト(TLSとTLSv1.1)を取得したらどうなりますか? – Bruno

関連する問題