我們有一小組運行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
爲空。
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的實例?
你試過這裏顯示HTTPS的PARAMS和測試: //blogs.oracle.com/java-platform-group/jdk-8-will-use-tls-12-as-default – pvg
此外,您可能希望包含一個簡短的[MCVE],以便JDK 7上的其他用戶可以重現你正在嘗試。 – pvg
您不應啓用所有支持的協議,因爲它們包含不安全的匿名密碼套件。 – EJP