web-dev-qa-db-fra.com

CertificateException: aucun nom correspondant à ssl.someUrl.de trouvé

J'essaie de me connecter à l'un de mes serveurs via SSL, avec Java. J'ai essayé beaucoup d'options ici, c'est mon meilleur essai:

Je génère un jssecacerts avec le script recommendet: http://blogs.Oracle.com/andreas/resource/InstallCert.Java avec la commande: Java InstallCert ssl. someUrl.de changeit

après cela, j'ai fait la commande une deuxième fois:

Loading KeyStore jssecacerts...
Opening connection to ssl.someUrl.de:443...
Starting SSL handshake...

No errors, certificate is already trusted

Server sent 1 certificate(s):

 1 Subject [email protected], CN=plesk, OU=Plesk, O=Parallels, L=Hernd
on, ST=Virginia, C=US
   Issuer  [email protected], CN=plesk, OU=Plesk, O=Parallels, L=Hernd
on, ST=Virginia, C=US
   sha1    f1 0d 2c 54 05 e1 32 19 a0 52 5e e1 81 6c a3 a5 83 0d dd 67
   md5     f0 b3 be 5e 5f 6e 90 d1 bc 57 7a b2 81 ce 7d 3d

Enter certificate to add to trusted keystore or 'q' to quit: [1]

J'ai copié le fichier dans le répertoire par défaut et j'ai chargé le certificat dans Java trustStore

System.setProperty("javax.net.ssl.trustStore", "C:\\Program Files (x86)\\Java\\jre6\\lib\\security\\jssecacerts");
System.setProperty("javax.net.ssl.trustStorePassword","changeit");

Ensuite j'essaye de me connecter

URL url = new URL("https://ssl.someUrl.de/");
URLConnection conn = url.openConnection();
BufferedReader rd = new BufferedReader(new InputStreamReader(conn.getInputStream()));

Et j'obtiens une erreur sur la 3ème ligne: (Aucun nom correspondant à ssl.someUrl.de trouvé)

javax.net.ssl.SSLHandshakeException: Java.security.cert.CertificateException: No name matching ssl.someUrl.de found

Est-ce la cause du certificat plesk par défaut ou quelque chose d'autre ne va pas?

Configuration: JRE 6.20, Netbeans 6.8, Windows7 64 bits

41
fehrlich

Il semble que le certificat du serveur auquel vous essayez de vous connecter ne correspond pas à son nom d'hôte.

Lorsqu'un client HTTPS se connecte à un serveur, il vérifie que le nom d'hôte dans le certificat correspond au nom d'hôte du serveur. Il ne suffit pas de faire confiance à un certificat, il doit également correspondre au serveur avec lequel vous souhaitez parler. (Par analogie, même si vous faites confiance à un passeport pour être légitime, vous devez toujours vérifier qu'il s'agit bien de la personne à laquelle vous voulez parler, et pas seulement de tout passeport auquel vous auriez confiance pour être légitime.)

En HTTP, cela se fait en vérifiant que:

  • le certificat contient un autre nom de sujet DNS (il s'agit d'une extension standard) correspondant au nom d'hôte;

  • à défaut, le dernier CN de votre nom distinctif de sujet (c'est le nom principal si vous le souhaitez) correspond au nom d'hôte. (Voir RFC 2818.)

Il est difficile de dire quel est le nom alternatif du sujet sans avoir le certificat (bien que, si vous vous connectez avec votre navigateur et vérifiez son contenu plus en détail, vous devriez pouvoir le voir.) Le nom distinctif du sujet semble être:

[email protected], CN=plesk, OU=Plesk, O=Parallels, L=Herndon, ST=Virginia, C=US

(Il faudrait donc que ce soit CN = ssl.someUrl.de au lieu de CN = plesk, si vous n'avez pas déjà un autre nom de sujet avec DNS: ssl.someUrl.de; je suppose que non.)

Vous pourrez peut-être contourner la vérification du nom d'hôte à l'aide de HttpsURLConnection.setHostnameVerifier (..) . Il ne devrait pas être trop difficile d'écrire un HostnameVerifier personnalisé qui contourne la vérification, bien que je suggère de le faire uniquement lorsque le certificat est celui qui est spécifiquement concerné ici. Vous devriez pouvoir l'obtenir en utilisant l'argument SSLSession et sa méthode getPeerCertificates ().

(De plus, vous n'avez pas besoin de définir les propriétés javax.net.ssl. * Comme vous l'avez fait, car vous utilisez quand même les valeurs par défaut.)

Alternativement, si vous contrôlez le serveur auquel vous vous connectez et son certificat, vous pouvez en créer un certificat qui correspond aux règles de dénomination ci-dessus (le CN devrait être suffisant, bien que le nom alternatif soumis soit une amélioration). Si un certificat auto-signé est assez bon pour ce que vous nommez, assurez-vous que son nom commun (CN) est le nom d'hôte auquel vous essayez de parler (pas l'URL complète, juste le nom d'hôte).

58
Bruno

Dans Java 8, vous pouvez ignorer la vérification du nom du serveur avec le code suivant:

HttpsURLConnection.setDefaultHostnameVerifier ((hostname, session) -> true);

Cependant, cela ne doit être utilisé que dans le développement!

25
jamming

J'ai créé une méthode fixUntrustCertificate (), donc lorsque je traite avec un domaine qui n'est pas dans des autorités de certification de confiance, vous pouvez appeler la méthode avant la demande. Ce code fonctionnera après Java1.4. Cette méthode s'applique à tous les hôtes:

public void fixUntrustCertificate() throws KeyManagementException, NoSuchAlgorithmException{


        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 = SSLContext.getInstance("SSL");
        sc.init(null, trustAllCerts, new Java.security.SecureRandom());
        HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());

        HostnameVerifier allHostsValid = new HostnameVerifier() {
            public boolean verify(String hostname, SSLSession session) {
                return true;
            }
        };

        // set the  allTrusting verifier
        HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid);
}
13
Cassio Seffrin

J'ai trouvé une bonne résolution ici: http://www.mkyong.com/webservices/jax-ws/Java-security-cert-certificateexception-no-name-matching-localhost-found/

Mais mon problème était un peu différent et l'a résolu différemment.

Le service Web était sur l'hôte distant. Par exemple: https://some.remote.Host/MyWebService?wsdl

Mais il n'était disponible que par IP pour tous les clients, mais un certificat a été créé pour le domaine: some.remote.Host (CN = some.remote.Host). Et ce domaine ne peut pas être résolu par IP car il n'est pas présenté dans DNS).

Donc, le même problème est apparu: si j'utilise IP pour me connecter au service Web par SSL, il ne peut pas être atteint car le certificat CN = some.remote.Host et ce n'est pas égal au nom d'hôte que j'ai spécifié (c.-à-d. IP hôte) .

Je l'ai résolu en faisant correspondre ce nom d'hôte avec IP dans le fichier/etc/hosts. Le problème a été corrigé.

Mais dans le cas où le service Web est hébergé sur le serveur d'application localhost, il pense que cela devrait être résolu comme mkyong décrit dans son article.

4
Zaur_M

Si vous recherchez une erreur Kafka, cela peut être dû à la mise à niveau de la version de Kafka de 1.x vers 2.x.

javax.net.ssl.SSLHandshakeException: problème général SSLEngine ... javax.net.ssl.SSLHandshakeException: problème général SSLEngine ... Java.security.cert.CertificateException: aucune correspondance de nom *** trouvée

ou

[Producer clientId = producteur-1] La connexion au nœud -2 a échoué l'authentification en raison de: Échec de l'établissement de la liaison SSL

La valeur par défaut de ssl.endpoint.identification.algorithm a été remplacée par https, qui effectue la vérification du nom d'hôte (des attaques man-in-the-middle sont possibles sinon). Définissez ssl.endpoint.identification.algorithm sur une chaîne vide pour restaurer le comportement précédent. Apache Kafka Changements notables dans 2.0.

Solution: SslConfigs.SSL_ENDPOINT_IDENTIFICATION_ALGORITHM_CONFIG, ""

1
Senchan Sue

Le nom du serveur doit être le même que le prénom/nom que vous donnez lors de la création d'un certificat

1
user2181029