299 votes

Impossible de trouver un chemin de certification valide vers la cible demandée - erreur même après l'importation du certificat

J'ai un client Java qui essaie d'accéder à un serveur avec un certificat auto-signé.

Lorsque j'essaie de poster sur le serveur, je reçois l'erreur suivante:

unable to find valid certification path to requested target

Ayant fait quelques recherches sur le problème, j'ai ensuite fait ce qui suit.

  1. Enregistré le nom de domaine de mes serveurs sous forme de fichier root.cer.

  2. Dans le JRE de mon serveur Glassfish, j'ai exécuté ceci:

    keytool -import -alias example -keystore cacerts -file root.cer
  3. Pour vérifier que le certificat a bien été ajouté à mon cacert, j'ai fait ceci:

    keytool -list -v -keystore cacerts

    Je peux voir que le certificat est présent.

  4. J'ai ensuite redémarré Glassfish et réessayé le 'post'.

Je reçois toujours la même erreur.

J'ai l'impression que c'est parce que mon Glassfish ne lit pas réellement le fichier cacert que j'ai modifié mais peut-être un autre.

Avez-vous déjà rencontré ce problème et pouvez-vous me guider dans la bonne direction?

2 votes

Juste pour clarifier "J'ai un client Java qui essaie d'accéder à un serveur avec un certificat auto-signé.": vous parlez d'utiliser des certificats client qui sont auto-signés, n'est-ce pas? Y a-t-il une configuration spécifique pour les paramètres de votre connecteur sur Glassfish (paramètres du magasin de confiance, en particulier)?

0 votes

"J'ai un client Java essayant d'accéder à un serveur avec un certificat auto-signé." : tu parles d'utiliser des certificats de client qui sont auto-signés, n'est-ce pas ? - oui.

1 votes

J'ai trouvé 2 paramètres dans Glassfish JVM : -Djavax.net.ssl.keyStore=${com.sun.aas.instanceRoot}/config/‌​keystore.jks et -Djavax.net.ssl.trustStore=${com.sun.aas.instanceRoot}/confi‌​g/cacerts.jks. Maintenant, je dois ajouter mon certificat à l'un d'eux. Pouvez-vous confirmer que c'est le keystore auquel je dois l'ajouter ?

7voto

Danny Mor Points 547

J'ai eu le même problème avec sbt.
Il a essayé de récupérer les dépendances depuis repo1.maven.org via ssl
mais a dit qu'il était "impossible de trouver un chemin de certification valide vers l'URL cible demandée".
alors j'ai suivi cet article et j'ai encore échoué à vérifier une connexion.
J'ai alors lu à ce sujet et trouvé que le certificat racine n'était pas suffisant, comme suggéré par l'article, donc -
ce qui a fonctionné pour moi était d'importer les certificats CA intermédiaires dans le keystore.
J'ai en fait ajouté tous les certificats de la chaîne et cela a fonctionné à merveille.

0 votes

A rencontré la même chose : seulement l'importation de la racine ne fonctionne pas. Lors de l'importation de l'intermédiaire, cela fonctionne. Quelle pourrait être la raison de ceci ?

0 votes

Vous avez seulement besoin de l'un des certificats de signature, pas tous.

5voto

Marcello de Sales Points 1771

Solution lors de la migration de JDK 8 à JDK 10

JDK 10

root@c339504909345:/opt/jdk-minimal/jre/lib/security #  keytool -cacerts -list
Enter keystore password:
Keystore type: JKS
Keystore provider: SUN

Your keystore contains 80 entries

JDK 8

root@c39596768075:/usr/lib/jvm/java-8-openjdk-amd64/jre/lib/security/cacerts #  keytool -cacerts -list
Enter keystore password:
Keystore type: JKS
Keystore provider: SUN

Your keystore contains 151 entries

Étapes pour corriger

  • J'ai supprimé le certificat JDK 10 et je l'ai remplacé par celui de JDK 8
  • Étant donné que je construis des images Docker, j'ai pu le faire rapidement en utilisant des constructions multi-étapes
    • Je construis un JRE minimal en utilisant jlink comme /opt/jdk/bin/jlink \ --module-path /opt/jdk/jmods...

Voici donc les différents chemins et la séquence des commandes...

# Java 8
COPY --from=marcellodesales-springboot-builder-jdk8 /usr/lib/jvm/java-8-openjdk-amd64/jre/lib/security/cacerts /etc/ssl/certs/java/cacerts

# Java 10
RUN rm -f /opt/jdk-minimal/jre/lib/security/cacerts
RUN ln -s /etc/ssl/certs/java/cacerts /opt/jdk-minimal/jre/lib/security/cacerts

0 votes

Le dernier extrait pourrait être des parties d'un script Docker. Les blocs précédents étaient probablement destinés à être des commandes shell.

4voto

Steve T Points 109

Je travaille sur un tutoriel pour les services web REST sur www.udemy.com (REST Java Web Services). L'exemple dans le tutoriel a dit que pour avoir SSL, nous devons avoir un dossier appelé "trust_store" dans mon projet "client" eclipse qui devrait contenir un fichier "keystore" (nous avions un projet "client" pour appeler le service, et un projet "service" qui contenait le service web REST - 2 projets dans le même espace de travail eclipse, un le client, l'autre le service). Pour simplifier les choses, ils ont dit de copier "keystore.jks" du serveur d'application glassfish (glassfish\domains\domain1\config\keystore.jks) que nous utilisons et de le mettre dans ce dossier "trust_store" qu'ils m'avaient fait créer dans le projet client. Cela semble logique : les certificats auto-signés dans le keystore du serveur correspondraient aux certificats dans le trust_store du client. En faisant cela, j'obtenais l'erreur que mentionne le message original. J'ai googlé et j'ai lu que l'erreur est due au fait que le fichier "keystore.jks" sur le client ne contient pas un certificat de confiance/signé, que le certificat qu'il trouve est auto-signé.

Pour être clair, permettez-moi de dire que, selon ma compréhension, le "keystore.jks" contient des certificats auto-signés, et le fichier "cacerts.jks" contient des certificats de CA (signés par la CA). Le "keystore.jks" est le "keystore" et le "cacerts.jks" est le "trust store". Comme "Bruno", un commentateur, le dit ci-dessus, "keystore.jks" est local, et "cacerts.jks" est pour les clients distants.

Donc, je me suis dit, hey, glassfish a aussi le fichier "cacerts.jks", qui est le fichier trust_store de glassfish. cacerts.jsk est censé contenir des certificats de CA. Et apparemment j'ai besoin que mon dossier trust_store contienne un fichier keystore qui a au moins un certificat de CA. Donc, j'ai essayé de mettre le fichier "cacerts.jks" dans le dossier "trust_store" que j'avais créé, sur mon projet client, et de changer les propriétés VM pour pointer vers "cacerts.jks" au lieu de "keystore.jks". Cela a éliminé l'erreur. Je suppose que tout ce dont il avait besoin était un certificat de CA pour fonctionner.

Cela pourrait ne pas être idéal pour la production, ou même pour le développement au-delà de simplement faire fonctionner quelque chose. Par exemple, vous pourriez probablement utiliser la commande "keytool" pour ajouter des certificats de CA au fichier "keystore.jks" sur le client. Mais de toute façon, j'espère que cela au moins restreint les scénarios possibles qui pourraient causer l'erreur.

DE PLUS: mon approche semblait être utile pour le client (certificat serveur ajouté au trust_store client), il semble que les commentaires ci-dessus pour résoudre le message original sont utiles pour le serveur (certificat client ajouté au trust_store serveur). Cheers.

Configuration du projet Eclipse :

  • MonProjetClient
  • src
  • test
  • Bibliothèque du système JRE
  • ...
  • trust_store
    ---cacerts.jks ---keystore.jks

Extrait du fichier MyProjetClient.java :

static {
  // Configurer l'emplacement et le mot de passe du trustStore
  System.setProperty("javax.net.ssl.trustStore","trust_store/cacerts.jks");
  // commenter la ligne ci-dessous
  System.setProperty("javax.net.ssl.trustStore","trust_store/keystore.jks");
  System.setProperty("javax.net.ssl.trustStorePassword", "changeit");
  //System.setProperty("javax.net.debug", "all");

  // pour le test en local seulement
  javax.net.ssl.HttpsURLConnection.setDefaultHostnameVerifier(new javax.net.ssl.HostnameVerifier() {
        public boolean verify(String hostname, javax.net.ssl.SSLSession sslSession) {
          return hostname.equals("localhost");
        }

  });
}

2voto

gary69 Points 477

Mon problème était qu'un courtier de sécurité d'accès Cloud, NetSkope, avait été installé sur mon ordinateur portable professionnel lors d'une mise à jour logicielle. Cela altérait la chaîne de certificats et je n'étais toujours pas en mesure de me connecter au serveur via mon client java après avoir importé l'ensemble de la chaîne dans mon dépôt de clés cacerts. J'ai désactivé NetSkope et j'ai pu me connecter avec succès.

0 votes

Que se passe-t-il si vous ne pouvez pas désactiver netskope ? (son logiciel d'entreprise)

1voto

0x7E1 Points 21

Vérifiez si le fichier $JAVA_HOME/lib/security/cacerts existe! Dans mon cas, ce n'était pas un fichier mais un lien vers /etc/ssl/certs/java/cacerts et en plus, c'était un lien vers lui-même (QUOI???) donc à cause de cela, la JVM ne peut pas trouver le fichier.

Solution: Copiez le vrai fichier cacerts (vous pouvez le faire à partir d'un autre JDK) dans le répertoire /etc/ssl/certs/java/ et cela résoudra votre problème :)

0 votes

En effet, JDK maintient un lien et peut-être pour des raisons de compatibilité avec les anciennes APIs, SDKs... J'ai réussi à faire la même chose... Je passe de JDK 8 à JDK 10 et j'utilise Docker donc j'avais juste besoin de copier les cacerts d'une image à une autre... J'ai créé le lien de la même manière exacte... rm -f /opt/jdk-minimal/jre/lib/security/cacerts ; ln -s /etc/ssl/certs/java/cacerts /opt/jdk-minimal/jre/lib/security/cacerts

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X