为了在 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() 函数。