Java SSL:如何禁用主机名验证
2022-09-01 03:51:48
标准 java SSL 套接字有没有办法禁用具有属性的 ssl 连接的主机名验证?到目前为止,我发现的唯一方法是编写一个主机名验证器,该验证器始终返回true。
Weblogic提供了这种可能性,可以使用以下属性禁用主机名验证:
-Dweblogic.security.SSL.ignoreHostnameVerify
标准 java SSL 套接字有没有办法禁用具有属性的 ssl 连接的主机名验证?到目前为止,我发现的唯一方法是编写一个主机名验证器,该验证器始终返回true。
Weblogic提供了这种可能性,可以使用以下属性禁用主机名验证:
-Dweblogic.security.SSL.ignoreHostnameVerify
应该可以创建覆盖默认值的自定义java代理:HostnameVerifier
import javax.net.ssl.*;
import java.lang.instrument.Instrumentation;
public class LenientHostnameVerifierAgent {
public static void premain(String args, Instrumentation inst) {
HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() {
public boolean verify(String s, SSLSession sslSession) {
return true;
}
});
}
}
然后只需添加到程序的java启动参数中即可。-javaagent:LenientHostnameVerifierAgent.jar
来自@Nani的答案在Java 1.8u181中不再有效。您仍然需要使用自己的 TrustManager,但它需要是一个而不是一个 :X509ExtendedTrustManager
X509TrustManager
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.Socket;
import java.net.URL;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.X509Certificate;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLEngine;
import javax.net.ssl.SSLHandshakeException;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509ExtendedTrustManager;
public class Test {
public static void main (String [] args) throws IOException {
// This URL has a certificate with a wrong name
URL url = new URL ("https://wrong.host.badssl.com/");
try {
// opening a connection will fail
url.openConnection ().connect ();
} catch (SSLHandshakeException e) {
System.out.println ("Couldn't open connection: " + e.getMessage ());
}
// Bypassing the SSL verification to execute our code successfully
disableSSLVerification ();
// now we can open the connection
url.openConnection ().connect ();
System.out.println ("successfully opened connection to " + url + ": " + ((HttpURLConnection) url.openConnection ()).getResponseCode ());
}
// Method used for bypassing SSL verification
public static void disableSSLVerification () {
TrustManager [] trustAllCerts = new TrustManager [] {new X509ExtendedTrustManager () {
@Override
public void checkClientTrusted (X509Certificate [] chain, String authType, Socket socket) {
}
@Override
public void checkServerTrusted (X509Certificate [] chain, String authType, Socket socket) {
}
@Override
public void checkClientTrusted (X509Certificate [] chain, String authType, SSLEngine engine) {
}
@Override
public void checkServerTrusted (X509Certificate [] chain, String authType, SSLEngine engine) {
}
@Override
public java.security.cert.X509Certificate [] getAcceptedIssuers () {
return null;
}
@Override
public void checkClientTrusted (X509Certificate [] certs, String authType) {
}
@Override
public void checkServerTrusted (X509Certificate [] certs, String authType) {
}
}};
SSLContext sc = null;
try {
sc = SSLContext.getInstance ("SSL");
sc.init (null, trustAllCerts, new java.security.SecureRandom ());
} catch (KeyManagementException | NoSuchAlgorithmException e) {
e.printStackTrace ();
}
HttpsURLConnection.setDefaultSSLSocketFactory (sc.getSocketFactory ());
}
}