I am writing a simple REST api client based on JDK11 HttpClient, simple code as below:
public class MyClass {
private static final X509TrustManager TRUST_MANAGER = new X509TrustManager() {
public void checkClientTrusted(X509Certificate[] xcs, String string) {
}
public void checkServerTrusted(X509Certificate[] xcs, String string) {
}
public X509Certificate[] getAcceptedIssuers() {
return null;
}
};
private static HttpClient getNewHttpClient() {
int timeout = 600;
try {
HttpsURLConnection.setDefaultHostnameVerifier((hostname, session) -> true);
SSLContext sslContext = SSLContext.getInstance("TLSv1.2");
sslContext.init(null, new TrustManager[]{TRUST_MANAGER}, new SecureRandom());
// Install the all-trusting host verifier
HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory());
//Set SSL parameters
SSLParameters parameters = new SSLParameters();
parameters.setEndpointIdentificationAlgorithm("HTTPS");
HttpClient httpClient = HttpClient.newBuilder()
.connectTimeout(Duration.ofMillis(timeout * 1000))
.sslContext(sslContext)
.sslParameters(parameters)
.build();
return httpClient;
} catch (Exception e) {
logger.warn("Unable to create HttpClient with disabled SSL Certificate verifying, default client will be used", e);
return HttpClient.newHttpClient();
}
}
public static void main(String[] args) {
HttpRequest requestBuilder = HttpRequest.newBuilder()
.uri(URI.create("https://somehostname.xx.xxx.net"))
.GET()
.build();
getNewHttpClient().send(request, HttpResponse.BodyHandlers.ofString());
}
}
Problem is that when I try to open some SSL domain I get an error:
Caused by: java.security.cert.CertificateException: No subject alternative DNS name matching somehostname.xx.xxx.net found.
How can I solve this problem?
While turning hostname verification off completly (i.e. for the whole VM) may be an option it may be dangerous. You can also disable hostname verification if you derive your TRUST_MANAGER from javax.net.ssl.X509ExtendedTrustManager.
private static final TrustManager DUMMY_TRUST_MANAGER = new X509ExtendedTrustManager() {
@Override
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return new java.security.cert.X509Certificate[0];
}
@Override
public void checkServerTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException { }
@Override
public void checkClientTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException { }
@Override
public void checkServerTrusted(X509Certificate[] chain, String authType, SSLEngine engine) throws CertificateException { }
@Override
public void checkServerTrusted(X509Certificate[] chain, String authType, Socket socket) throws CertificateException { }
@Override
public void checkClientTrusted(X509Certificate[] chain, String authType, SSLEngine engine) throws CertificateException { }
@Override
public void checkClientTrusted(X509Certificate[] chain, String authType, Socket socket) throws CertificateException { }
};
Of course this will also completely disable any checks of the certificates presented to your client.
There is also an open Issue at https://bugs.openjdk.java.net/browse/JDK-8213309 to add API to the JDK to specifically turn off hostname verification. If you have access too the openjdk bug database you may vote for the issue.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With