Existe-t-il un moyen pour les sockets SSL Java standard de désactiver la vérification du nom d'hôte pour les connexions SSL avec une propriété? La seule façon que j'ai trouvée jusqu'à présent est d'écrire un vérificateur de nom d'hôte qui renvoie vrai tout le temps.
Weblogic fournit cette possibilité, il est possible de désactiver la vérification du nom d'hôte avec la propriété suivante:
-Dweblogic.security.SSL.ignoreHostnameVerify
Il devrait être possible de créer un agent Java personnalisé qui remplace la valeur par défaut 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;
}
});
}
}
Ensuite, ajoutez simplement -javaagent:LenientHostnameVerifierAgent.jar
aux arguments de démarrage Java du programme.
Il n'y a pas de vérification du nom d'hôte dans les sockets SSL Java standard ou même SSL, c'est pourquoi vous ne pouvez pas le définir à ce niveau. La vérification du nom d'hôte fait partie de HTTPS (RFC 2818): c'est pourquoi elle se manifeste sous la forme javax.net.ssl.HostnameVerifier, qui est appliquée à une connexion HttpsURLConnection.
J'ai également eu le même problème lors de l'accès aux services Web RESTful. Et je leur avec le code ci-dessous pour surmonter le problème:
public class Test {
//Bypassing the SSL verification to execute our code successfully
static {
disableSSLVerification();
}
public static void main(String[] args) {
//Access HTTPS URL and do something
}
//Method used for bypassing SSL verification
public static void disableSSLVerification() {
TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() {
public Java.security.cert.X509Certificate[] getAcceptedIssuers() {
return null;
}
public void checkClientTrusted(X509Certificate[] certs, String authType) {
}
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 e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
HostnameVerifier allHostsValid = new HostnameVerifier() {
public boolean verify(String hostname, SSLSession session) {
return true;
}
};
HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid);
}
}
Cela a fonctionné pour moi. essayez-le !!
Si vous utilisez le client HTTP 4 d'Apache:
SSLConnectionSocketFactory sslConnectionSocketFactory =
new SSLConnectionSocketFactory(sslContext,
new String[] { "TLSv1.2" }, null, new HostnameVerifier() {
public boolean verify(String arg0, SSLSession arg1) {
return true;
}
});
La réponse de @Nani ne fonctionne plus avec Java 1.8u181. Vous devez toujours utiliser votre propre TrustManager, mais il doit s'agir d'un X509ExtendedTrustManager
au lieu d'un 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 ());
}
}