gpt4 book ai didi

Java、Apache HttpClient、TLSv1.2 和 OpenJDK 7

转载 作者:塔克拉玛干 更新时间:2023-11-01 22:21:49 27 4
gpt4 key购买 nike

我们有一小组运行 OpenJDK v1.7.0_111 的 Tomcat 服务器。我们计划在今年夏天升级并迁移它们,但我们发现我们与之交互的客户端 API 在短期内需要 TLSv1.2。我的最终愿望是找到一个配置更改来实现这一点。

那里托管的应用程序以非常直接的方式创建它的 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() 方法来确定哪些协议(protocol)可用。请注意,在我的例子中,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 实例?

最佳答案

jdk.tls.client.protocols 仅适用于您未使用的 Java 8(可能还有 9)。

https.protocols 仅在 httpclient 不使用的 HttpsURLConnection 中默认工作。

deployment.* 仅适用于您未使用的 JNLP 和 applet(如果任何浏览器仍允许 applet)。

如前所述,至少对于 4.5,假设您使用 HttpClientBuilderHttpClients(您没有说), 就是分别使用.useSystemProperties().createSystem();这些确实使用与*URLConnection 相同的系统属性——或者至少其中许多包括https.protocols。您应该检查此集合中包含的任何其他属性均未配置为执行您不希望执行的操作。这确实需要更改应用程序,但不需要将它们更改为“专门请求...TLSv1.2”。

除此之外,您可以配置 SSLConnectionSocketFactory 以指定允许的确切协议(protocol),如 the Q linked by @pvg 中所述,或 SSLContexts.custom().useProtocol(String).build() 来指定上限——这对你的情况来说已经足够了,因为向需要的服务器提供“最高 1.2”的范围1.2 会选择 1.2。

关于Java、Apache HttpClient、TLSv1.2 和 OpenJDK 7,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43772426/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com