gpt4 book ai didi

tls1.2 - 如何在 Java 中更改客户端 TLS 首选项?

转载 作者:行者123 更新时间:2023-12-04 11:27:57 24 4
gpt4 key购买 nike

我正在尝试向 Java 中的端点发出 POST 请求,当我尝试发送请求时,出现以下错误:

Caused by: javax.net.ssl.SSLHandshakeException: The server selected protocol version TLS10 is not accepted by client preferences [TLS13, TLS12]

这是我到目前为止
Map<Object, Object> data = new HashMap<>();
data.put("username","foo");
data.put("password","bar");

String url = "https://google.com";

HttpRequest request = HttpRequest.newBuilder()
.POST(buildFormDataFromMap(data))
.uri(URI.create(url))
.build();

try{
HttpResponse<String> response = httpClient.send(request,
HttpResponse.BodyHandlers.ofString());
System.out.println(response.statusCode());
System.out.println(response.body());
} catch (Exception e){
e.printStackTrace();
}

然后当我运行代码时,发送请求/制作响应对象时会抛出错误。我的问题是,如果服务器与客户端的 TLS 首选项不同,我该如何更改 Java 中的首选项,以便它仍然可以发出请求?

最佳答案

为了在 jdk 11 中解决这个问题,我必须创建一个 javax.net.ssl.SSLParameters 对象来启用“TLSv1”等:

SSLParameters sslParameters = new SSLParameters();
sslParameters.setProtocols(new String[]{"TLSv1", "TLSv1.1", "TLSv1.2", "TLSv1.3"});

然后创建 HttpClient 并添加 sslParamters 对象:
HttpClient httpClient = HttpClient.newBuilder()
.sslParameters(sslParameters)
.build();

如果您还想禁用主机名验证,请在 HttpClient 初始化之前添加以下代码;
final Properties props = System.getProperties(); 
props.setProperty("jdk.internal.httpclient.disableHostnameVerification", Boolean.TRUE.toString());

您也可以添加一个新的 TrustManager 来信任所有证书(自签名)。
为此,请将以下代码添加到您的类中:
    TrustManager[] trustAllCerts = new TrustManager[] { 
new X509TrustManager() {
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[0];
}
public void checkClientTrusted(
java.security.cert.X509Certificate[] certs, String authType) {
}
public void checkServerTrusted(
java.security.cert.X509Certificate[] certs, String authType) {
}
}
};

在此之后,您必须创建一个 SSLContext 对象并添加 TrustManger 对象:
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, trustAllCerts, new java.security.SecureRandom());

最后像这样改变 HttpClient 初始化:
httpClient = HttpClient.newBuilder()
.sslContext(sslContext)
.sslParameters(sslParameters)
.build()

这是一个完整的类示例:
import java.net.http.HttpClient;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.X509Certificate;
import java.util.Properties;

import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLParameters;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

public class HttpSSLClient {

private SSLContext sslContext;
private SSLParameters sslParameters;
private HttpClient httpClient;

public HttpSSLClient() throws KeyManagementException, NoSuchAlgorithmException {

sslParameters = new SSLParameters();
sslParameters.setProtocols(new String[]{"TLSv1", "TLSv1.1", "TLSv1.2", "TLSv1.3"});

sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, trustAllCerts, new java.security.SecureRandom());

final Properties props = System.getProperties();
props.setProperty("jdk.internal.httpclient.disableHostnameVerification", Boolean.TRUE.toString());

httpClient = HttpClient.newBuilder()
.sslContext(sslContext)
.sslParameters(sslParameters)
.build();
}

public HttpClient getHttplClient() {
return httpClient;
}

TrustManager[] trustAllCerts = new TrustManager[] {
new X509TrustManager() {
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[0];
}
public void checkClientTrusted(
java.security.cert.X509Certificate[] certs, String authType) {
}
public void checkServerTrusted(
java.security.cert.X509Certificate[] certs, String authType) {
}
}
};
}

您可以在调用 HttpRequest 时使用 getHttplClient() 函数。

关于tls1.2 - 如何在 Java 中更改客户端 TLS 首选项?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58718383/

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