2017-05-04 18 views
3

OpenJDK v1.7.0_111を実行するTomcatサーバーの小さなグループがあります。今夏にそれらをアップグレードして移行する計画がありますが、私たちがやり取りするクライアントAPIが近いうちにTLSv1.2を必要とする動きがあることがわかりました。私の最終的な欲求は、これを可能にする構成変更を見つけることです。Java、Apache HttpClient、TLSv1.2&OpenJDK 7

アプリケーションは、それはかなりまっすぐ進む方法で、SSLコンテキストのが作成されますホストさ:

SSLContext sslContext = SSLContexts.createDefault() 
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext); 

SSLContextsは、ApacheのHTTPClientのライブラリ(バージョン4.4.1)からであり、それはSSLを作成する方法と、かなりまっすぐ進むもありますコンテキスト:

public static SSLContext createDefault() throws SSLInitializationException { 
    try { 
     SSLContext ex = SSLContext.getInstance("TLS"); 
     ex.init((KeyManager[])null, (TrustManager[])null, (SecureRandom)null); 
     return ex; 
    } catch (NoSuchAlgorithmException var1) { 
     throw new SSLInitializationException(var1.getMessage(), var1); 
    } catch (KeyManagementException var2) { 
     throw new SSLInitializationException(var2.getMessage(), var2); 
    } 
} 

そしてSSLConnectionSocketFactoryクラスを掘り、単に使用可能であるプロトコルを決定するSSLSocket.getEnabledProtocols()方法を使っていることが表示されます。私の場合、this.supportedProtocolsはnullであることに注意してください。

public Socket createLayeredSocket(Socket socket, String target, int port, HttpContext context) throws IOException { 
     SSLSocket sslsock = (SSLSocket)this.socketfactory.createSocket(socket, target, port, true); 
     if(this.supportedProtocols != null) { 
      sslsock.setEnabledProtocols(this.supportedProtocols); 
     } else { 
      String[] allProtocols = sslsock.getEnabledProtocols(); 
      ArrayList enabledProtocols = new ArrayList(allProtocols.length); 
      String[] arr$ = allProtocols; 
      int len$ = allProtocols.length; 

      for(int i$ = 0; i$ < len$; ++i$) { 
       String protocol = arr$[i$]; 
       if(!protocol.startsWith("SSL")) { 
        enabledProtocols.add(protocol); 
       } 
      } 

      if(!enabledProtocols.isEmpty()) { 
       sslsock.setEnabledProtocols((String[])enabledProtocols.toArray(new String[enabledProtocols.size()])); 
      } 
     } 

私がいる問題は、私はこれらのクライアントがTLSv1.2を必要とするAPIに接続するために取得することができませんよ、いくつかの予備テストを実行しながら、ということです。

次の例では、-Dhttps.protocols=TLSv1.2パラメータを含めることによってURLConnectionコードを完成させることができますが、接続するApache接続を取得できません。

public static void main(String[] args) throws Exception{ 
     String testURL = "https://testapi.com"; 

     SSLContext sslcontext = SSLContext.getInstance("TLS"); 
     sslcontext.init(null, null, null); 

     try { 
      SSLConnectionSocketFactory socketFactory = new SSLConnectionSocketFactory(sslcontext); 
      CloseableHttpClient client = HttpClients.custom().setSSLSocketFactory(socketFactory).build(); 

      HttpGet httpget = new HttpGet(testURL); 

      CloseableHttpResponse response = client.execute(httpget); 
      System.out.println("Response Code (Apache): " + response.getStatusLine().getStatusCode()); 
     } 
     catch (Exception e){ 
      System.err.println("Apache HTTP Client Failed"); 
      e.printStackTrace(); 
     } 

     try { 
      HttpsURLConnection urlConnection = (HttpsURLConnection) new URL(testURL).openConnection(); 
      urlConnection.setSSLSocketFactory(sslcontext.getSocketFactory()); 
      urlConnection.connect(); 
      System.out.println("Response Code (URLConnection): " + urlConnection.getResponseCode()); 
     } 
     catch (Exception e){ 
      System.err.println("HttpsURLConnection Failed"); 
      e.printStackTrace(); 
     } 

    } 

-Dhttps.protocols=TLSv1.2とともに私は運なし-Djdk.tls.client.protocols=TLSv1.2-Ddeployment.security.TLSv1.2=true JVMパラメータを試してみました。

この設定でTLSv1.2を有効にしてv8にアップグレードしたり、アプリケーションを特に変更してTLSv1.2のインスタンスを要求したりすることなく、どのようにすればよいでしょうか?

+0

までを使用するようにApacheのHttpClient 4.xを設定する推奨方法は、あなたがここに示されているのparamsやテストを試してみましたはhttps: //blogs.oracle.com/java-platform-group/jdk-8-will-use-tls-12-as-default – pvg

+0

さらに、短い[MCVE]を含めて、JDK 7の他のユーザーがあなたは試みている。 – pvg

+0

セキュリティで保護されていない匿名の暗号スイートが含まれているため、サポートされているすべてのプロトコルを有効にするべきではありません。 – EJP

答えて

3

jdk.tls.client.protocolsは、使用していないJava 8(およびおそらく9)のみで動作します。

https.protocolsは、httpclientが使用しないHttpsURLConnectionにデフォルトでのみ動作します。

deployment.*は、使用していないJNLPおよびアプレット(アプレットを許可するブラウザがあれば)にのみ適用されます。

述べたように、あなたのQへの答えは、少なくとも4.5、のためにあなたは(あなたが言っていなかった)HttpClientBuilderまたはHttpClientsを使用を想定し、それぞれ.createSystem()または.useSystemProperties()を使用することです。これらのdoは、*URLConnectionと同じシステムプロパティを使用します。または、少なくともそれらのうちの多くは、https.protocolsを含みます。このセットに含まれている他のプロパティのどれも、あなたが望まないことをするように設定されていないことを確認してください。このはアプリを変更する必要がありますが、は「特に要求する... TLSv1.2」を変更するものではありません。それ以外

あなたは上限を指定するthe Q linked by @pvg、またはSSLContexts.custom().useProtocol(String).build()のように許可される正確なプロトコルを指定するSSLConnectionSocketFactoryを設定することができます - サーバーに「1.2までの」範囲を提供するため、あなたのケースのために十分であるが、その1.2は1.2を選択する必要があります。ここで

+0

[このOpenJDK拡張リクエスト](https://bugs.openjdk.java.net/browse/JDK-JPN)を理解していれば、OpenJDK 7u91以降および6u115以上で 'jdk.tls.client.protocols'を実際に利用できるはずです。 8076369)。 – russianmario

0

は、特定のTLS/SSLバージョン

CloseableHttpClient client = HttpClientBuilder.create() 
    .setSSLSocketFactory(new SSLConnectionSocketFactory(SSLContext.getDefault(), new String[] { "TLSv1.2" }, null, SSLConnectionSocketFactory.getDefaultHostnameVerifier())) 
    .build(); 

投票dave_thompson_085の答え

関連する問題