web-dev-qa-db-fra.com

Java SSL: comment désactiver la vérification du nom d'hôte

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

33
paweloque

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.

25
Vadzim

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.

5
user207421

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 !!

3
Nani

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;
            }
      });
1
Eduardo Beninca

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 ());
   }
}
0
Markus Heberling