Résolution de javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: échec de la création du chemin PKIX Erreur?

426

Edit: - J'ai essayé de formater la question et accepté la réponse de manière plus présentable sur le mien Blog

Voici le numéro d'origine.

Je reçois cette erreur:

message détaillé sun.security.validator.ValidatorException: échec de la création du chemin PKIX:
sun.security.provider.certpath.SunCertPathBuilderException: impossible de trouver un chemin de certification valide vers la cible demandée

cause javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: échec de la construction du chemin PKIX: sun.security.provider.certpath.SunCertPathBuilderException: impossible de trouver un chemin de certification valide vers la cible demandée

J'utilise Tomcat 6 comme serveur Web. J'ai deux applications Web HTTPS installées sur différents Tomcats sur différents ports mais sur la même machine. Dites App1(port 8443)et App2(port 443). App1se connecte à App2. Lorsque je me App1connecte à, App2j'obtiens l'erreur ci-dessus. Je sais que c'est une erreur très courante, j'ai trouvé de nombreuses solutions sur différents forums et sites. J'ai l'entrée ci-dessous dans les server.xmldeux Tomcats:

keystoreFile="c:/.keystore" 
keystorePass="changeit"

Chaque site indique la même raison pour laquelle le certificat donné par app2 ne se trouve pas dans le magasin de confiance de app1 jvm. Cela semble être vrai également lorsque j'ai essayé de frapper la même URL dans le navigateur IE, cela fonctionne (avec réchauffement, il y a un problème avec le certificat de sécurité de ce site Web. Ici, je dis continuer sur ce site). Mais lorsque la même URL est atteinte par le client Java (dans mon cas), j'obtiens l'erreur ci-dessus. Donc, pour le mettre dans le truststore, j'ai essayé ces trois options:

Option 1

System.setProperty("javax.net.ssl.trustStore", "C:/.keystore");
System.setProperty("javax.net.ssl.trustStorePassword", "changeit");

Option2 Réglage ci-dessous dans la variable d'environnement

CATALINA_OPTS -- param name
-Djavax.net.ssl.trustStore=C:\.keystore -Djavax.net.ssl.trustStorePassword=changeit ---param value

Option3 Réglage ci-dessous dans la variable d'environnement

JAVA_OPTS -- param name
-Djavax.net.ssl.trustStore=C:\.keystore -Djavax.net.ssl.trustStorePassword=changeit ---param value

Mais rien n'a fonctionné .

Ce qui a finalement fonctionné est d'exécuter l'approche Java suggérée dans Comment gérer les certificats SSL invalides avec Apache HttpClient? par Pascal Thivent c'est-à-dire l'exécution du programme InstallCert.

Mais cette approche est très bien pour la configuration de devbox mais je ne peux pas l'utiliser dans un environnement de production.

Je me demande pourquoi trois approches mentionnées ci-dessus n'ont pas fonctionné alors que j'ai mentionné les mêmes valeurs dans server.xmldu app2serveur et les mêmes valeurs dans truststore en définissant

System.setProperty("javax.net.ssl.trustStore", "C:/.keystore") and System.setProperty("javax.net.ssl.trustStorePassword", "changeit");

dans le app1programme.

Pour plus d'informations, voici comment je fais la connexion:

URL url = new URL(urlStr);

URLConnection conn = url.openConnection();

if (conn instanceof HttpsURLConnection) {

  HttpsURLConnection conn1 = (HttpsURLConnection) url.openConnection();

  conn1.setHostnameVerifier(new HostnameVerifier() {
    public boolean verify(String hostname, SSLSession session) {
      return true;
    }
  });

  reply.load(conn1.getInputStream());
M Sach
la source
doublon possible de HttpClient et SSL
Marquis de Lorne
Assez étrangement, j'ai eu cette erreur lors de la communication entre des serveurs en cluster qui n'avaient aucun problème SSL individuellement. Une fois que j'ai correctement installé domainnamemes serveurs RHEL, le problème a disparu. J'espère que cela aide quelqu'un.
DavidG
Une autre chose à vérifier est que vous avez la dernière version de Java - j'obtenais une erreur similaire à cause de cela.
Redzarf
stackoverflow.com/questions/2893819/… - également pertinent et une réponse fantastique.
Siddhartha

Réponses:

406

Vous devez ajouter le certificat pour App2 au fichier truststore de la machine virtuelle Java utilisée situé à %JAVA_HOME%\lib\security\cacerts.

Vous pouvez d'abord vérifier si votre certificat est déjà dans le magasin de clés de confiance en exécutant la commande suivante: keytool -list -keystore "%JAVA_HOME%/jre/lib/security/cacerts"(vous n'avez pas besoin de fournir un mot de passe)

Si votre certificat est manquant, vous pouvez l'obtenir en le téléchargeant avec votre navigateur et en l'ajoutant au magasin de clés de confiance avec la commande suivante:

keytool -import -noprompt -trustcacerts -alias <AliasName> -file <certificate> -keystore <KeystoreFile> -storepass <Password>

Après l'importation, vous pouvez réexécuter la première commande pour vérifier si votre certificat a été ajouté.

Les informations Sun / Oracle peuvent être trouvées ici .

SimonSez
la source
6
Vous devrez utiliser le chemin complet, par exemple c: \ java \ jdk \ lib \ security \ cacerts
SimonSez
48
Comme l'a dit SimonSez, vous n'avez pas besoin d'un mot de passe, mais si vous le souhaitez, le mot de passe par défaut est "changeit".
Felix
16
De plus, sous Windows, vous devez exécuter le terminal en tant qu'administrateur, sinon vous obtenez l'erreur keytool error: java.io.FileNotFoundException ... (Access is denied)lorsque vous essayez d'importer votre certificat.
Felix
2
Ah @SimonSez tu es mon dieu. Mais pour y ajouter, il faut spécifier l'emplacement et le mot de passe du magasin de confiance comme mentionné par @M Sach pour le faire fonctionner.
BudsNanKis
2
Problèmes liés à Java 1.8. Nécessaire pour ajouter le cert comme décrit et utiliser Java <1.8
Tom Howard
180

javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: échec de la création du chemin PKIX: sun.security.provider.certpath.SunCertPathBuilderException: impossible de trouver un chemin de certification valide vers la cible demandée

• Lorsque j'ai eu l'erreur, j'ai essayé de rechercher la signification de l'expression sur Google et j'ai trouvé que ce problème se produit lorsqu'un serveur modifie son certificat SSL HTTPS et que notre ancienne version de java ne reconnaît pas l'autorité de certification racine (CA) .

• Si vous pouvez accéder à l'URL HTTPS dans votre navigateur, il est possible de mettre à jour Java pour reconnaître l'autorité de certification racine.

• Dans votre navigateur, accédez à l'URL HTTPS à laquelle Java n'a pas pu accéder. Cliquez sur la chaîne de certificats HTTPS (il y a une icône de verrouillage dans Internet Explorer), cliquez sur le verrou pour afficher le certificat.

• Allez dans «Détails» du certificat et «Copier dans un fichier». Copiez-le dans format Base64 (.cer) . Il sera enregistré sur votre bureau.

• Installez le certificat en ignorant toutes les alertes.

• Voici comment j'ai rassemblé les informations de certificat de l'URL à laquelle j'essayais d'accéder.

Maintenant, je devais faire ma version java pour connaître le certificat afin qu'il ne refuse plus de reconnaître l'URL. À cet égard, je dois mentionner que j'ai recherché sur Google que les informations du certificat racine restent par défaut dans la sécurité \ jre \ lib \ de JDK. emplacement , et le mot de passe par défaut pour accéder est: changeit.

Pour afficher les informations sur les cacerts, voici les procédures à suivre:

• Cliquez sur le bouton Démarrer -> Exécuter

• Tapez cmd. L'invite de commande s'ouvre (vous devrez peut-être l'ouvrir en tant qu'administrateur).

• Accédez à votre Java/jreX/bin répertoire

• Tapez ce qui suit

keytool -list -keystore D: \ Java \ jdk1.5.0_12 \ jre \ lib \ security \ cacerts

Il donne la liste des certificats actuels contenus dans le magasin de clés. Cela ressemble à ceci:

C: \ Documents and Settings \ NeelanjanaG> keytool -list -keystore D: \ Java \ jdk1.5.0_12 \ jre \ lib \ security \ cacerts

Entrez le mot de passe du magasin de clés: changez-le

Type de magasin de clés: jks

Fournisseur de magasin de clés: SUN

Votre keystore contient 44 entrées

verisignclass3g2ca, 26 mars 2004, trustedCertEntry,

Empreinte digitale du certificat (MD5): A2: 33: 9B: 4C: 74: 78: 73: D4: 6C: E7: C1: F3: 8D: CB: 5C: E9

entrustclientca, 9 janvier 2003, trustedCertEntry,

Empreinte digitale du certificat (MD5): 0C: 41: 2F: 13: 5B: A0: 54: F5: 96: 66: 2D: 7E: CD: 0E: 03: F4

thawtepersonalbasicca, 13 février 1999, trustedCertEntry,

Empreinte digitale du certificat (MD5): E6: 0B: D2: C9: CA: 2D: 88: DB: 1A: 71: 0E: 4B: 78: EB: 02: 41

addtrustclass1ca, 1er mai 2006, trustedCertEntry,

Empreinte digitale du certificat (MD5): 1E: 42: 95: 02: 33: 92: 6B: B9: 5F: C0: 7F: DA: D6: B2: 4B: FC

verisignclass2g3ca, 26 mars 2004, trustedCertEntry,

Empreinte digitale du certificat (MD5): F8: BE: C4: 63: 22: C9: A8: 46: 74: 8B: B8: 1D: 1E: 4A: 2B: F6

• Maintenant, je devais inclure le certificat précédemment installé dans les cacerts.

• Pour cela, voici la procédure:

keytool –import –noprompt –trustcacerts –alias ALIASNAME -file FILENAME_OF_THE_INSTALLED_CERTIFICATE -keystore PATH_TO_CACERTS_FILE -storepass PASSWORD

Si vous utilisez Java 7:

keytool –importcert –trustcacerts –alias ALIASNAME -file PATH_TO_FILENAME_OF_THE_INSTALLED_CERTIFICATE -keystore PATH_TO_CACERTS_FILE -storepass changeit

• Il ajoutera ensuite les informations du certificat dans le fichier cacert.

C'est la solution que j'ai trouvée pour l'exception mentionnée ci-dessus !!

NDeveloper
la source
5
Que faites-vous à l'expiration du certificat? Tout répéter (annuellement)?
ggkmath
7
Existe-t-il un moyen de le faire par programme?
Meshulam Silk
1
Pour les personnes confrontées à l'erreur PKIX, "Le chemin ne s'enchaîne avec aucune des ancres de confiance", cette solution n'a malheureusement pas résolu ce problème pour moi.
IcedDante
3
Une question - l'aliasName est-il l'adresse Web pour laquelle nous importons le certificat? Par exemple, si l'URL est domain.site.com/pages/service.asmx, l' alias doit être domain.site.com ou l'URL complète (domain.site.com/pages/service.asmx) ou doit-il également être préfixé par http : // ou c'est juste un nom arbitraire?
nanosoft
1
chemin: \ lib \ security> keytool -import -noprompt -trustcacerts -alias webCert -file webCertResource.cer -keystore c: / Users / Jackie / Desktop -storepass changeit I get "le système ne trouve pas le fichier spécifié"
Jesse
46

Comment travailler avec Tomcat 7

Je voulais prendre en charge un certificat auto-signé dans une application Tomcat, mais l'extrait de code suivant n'a pas fonctionné

import java.io.DataOutputStream;
import java.net.HttpURLConnection;
import java.net.URL;

public class HTTPSPlayground {
    public static void main(String[] args) throws Exception {

        URL url = new URL("https:// ... .com");
        HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();

        httpURLConnection.setRequestMethod("POST");
        httpURLConnection.setRequestProperty("Accept-Language", "en-US,en;q=0.5");
        httpURLConnection.setDoOutput(true);
        DataOutputStream wr = new DataOutputStream(httpURLConnection.getOutputStream());

        String serializedMessage = "{}";
        wr.writeBytes(serializedMessage);
        wr.flush();
        wr.close();

        int responseCode = httpURLConnection.getResponseCode();
        System.out.println(responseCode);
    }
}

c'est ce qui a résolu mon problème:

1) Téléchargez le .crtfichier

echo -n | openssl s_client -connect <your domain>:443 | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > ~/<your domain>.crt
  • remplacer <your domain>par votre domaine (par exemple jossef.com)

2) Appliquer le .crtfichier dans le cacertsmagasin de certificats Java

keytool -import -v -trustcacerts -alias <your domain> -file ~/<your domain>.crt -keystore <JAVA HOME>/jre/lib/security/cacerts -keypass changeit -storepass changeit
  • remplacer <your domain>par votre domaine (par exemple jossef.com)
  • remplacer <JAVA HOME>par votre répertoire personnel java

3) Hack it

Même si iv'e a installé mon certificat dans Javales magasins de certificats par défaut de, Tomcat l'ignore (il semble qu'il ne soit pas configuré pour utiliser les magasins de certificats par défaut de Java).

Pour pirater cela, ajoutez ce qui suit quelque part dans votre code:

String certificatesTrustStorePath = "<JAVA HOME>/jre/lib/security/cacerts";
System.setProperty("javax.net.ssl.trustStore", certificatesTrustStorePath);

// ...
Jossef Harush
la source
4
L'étape 2 a fait l'affaire pour moi en utilisant SpringBoot et Tomcat 7. Merci.
Tim Perry
Dois-je utiliser keytool de java utilisé par tomcat? Car sur un serveur je peux avoir plusieurs java
vikifor
@vikifor oui. Vous pouvez également l'exécuter pour tous les
répertoires
1
Ça a marché! merci une tonne @JossefHarush pour une réponse si utile!
Tom Taylor
1
mon problème a été résolu après avoir ajouté le segment de code de @Jossef Harush dans mon code.
Chamod Pathirana
10

Dans mon cas, le problème était que le serveur Web envoyait uniquement le certificat et l'autorité de certification intermédiaire, pas l'autorité de certification racine. L'ajout de cette option JVM a résolu le problème:-Dcom.sun.security.enableAIAcaIssuers=true

La prise en charge de la méthode d'accès caIssuers de l'extension Authority Information Access est disponible. Il est désactivé par défaut pour la compatibilité et peut être activé en définissant la propriété système com.sun.security.enableAIAcaIssuerssur la valeur true.

Si la valeur est true, l'implémentation PKIX de Sun de CertPathBuilder utilise les informations dans l'extension AIA d'un certificat (en plus des CertStores spécifiés) pour trouver le certificat CA émetteur, à condition qu'il s'agisse d'un URI de type ldap, http ou ftp.

La source

Guillaume
la source
Cela a en fait résolu mon problème, merci!
Luís Silva
6

Une autre raison pourrait être une version obsolète de JDK. J'utilisais la version 1.8.0_60 de jdk, la simple mise à jour vers la dernière version a résolu le problème du certificat.

Ali Ismayilov
la source
2
J'ai aussi eu le même problème. L'appel d'une API avec un certificat Lets Encrypt peut ne pas fonctionner avec les anciennes versions de Java car il n'est pas reconnu par les autorités de certification racine de confiance. La mise à jour de Java résoudra ce problème.
hertg
5

Mon fichier cacerts était totalement vide. J'ai résolu cela en copiant le fichier cacerts sur ma machine Windows (qui utilise Oracle Java 7) et je l'ai scpé dans ma boîte Linux (OpenJDK).

cd %JAVA_HOME%/jre/lib/security/
scp cacerts mylinuxmachin:/tmp

puis sur la machine linux

cp /tmp/cacerts /etc/ssl/certs/java/cacerts

Cela a très bien fonctionné jusqu'à présent.

Ryan Shillington
la source
1
Cela fonctionne à merveille si le problème est que vous utilisez une ancienne version de java qui n'a pas les derniers certificats.
atripathi
@atripathi que diriez-vous d'un Mac?
iOSAndroidWindowsMobileAppsDev
Il y avait un problème grave avec votre installation Java si le fichier cacerts était vide. Vous auriez dû tout réinstaller.
Marquis de Lorne
Peut-être, mais cette solution a fonctionné et rien ne s'est jamais passé après.
Ryan Shillington
5

Pour moi, cette erreur est également apparue lors de la tentative de connexion à un processus derrière un proxy inverse NGINX qui gérait le SSL.

Il s'est avéré que le problème était un certificat sans que toute la chaîne de certificats soit concaténée. Lorsque j'ai ajouté des certificats intermédiaires, le problème a été résolu.

J'espère que cela t'aides.

YaDa
la source
cela ressemble à ce que j'ai. pouvez-vous expliquer comment vous avez ajouté les certificats intermédiaires et où. im en utilisant le proxy inverse httpd et non NGINX.
Asaf Magen
cela m'a aidé dans mon cas parce que je suis en utilisant httpd: access.redhat.com/solutions/43575
Asaf Magen
Avec nginx, il utilise uniquement les fichiers .key et .pem pour la configuration SSL. Vous convertissez d'abord .crt en .pem (simplement: cp votrefichier.crt votrefichier.pem) puis pour la chaîne de certificats SSL: vous ajoutez le fichier .cer au dernier de .pem (cat yourfile.cer >> votrefichier.pem)
Thế Anh Nguyễn
5

En utilisant Tomcat 7 sous Linux, cela a fait l'affaire.

String certificatesTrustStorePath = "/etc/alternatives/jre/lib/security/cacerts";
System.setProperty("javax.net.ssl.trustStore", certificatesTrustStorePath);
System.setProperty("javax.net.ssl.trustStorePassword", "changeit");

Sous Linux, $JAVA_HOMEn'est pas toujours configuré, mais /etc/alternatives/jreindique généralement$JAVA_HOME/jre

Cedric Simon
la source
5

Le code ci-dessous fonctionne pour moi:

import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;

import javax.net.ssl.X509TrustManager;

public class TrustAnyTrustManager implements X509TrustManager {

public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
}

public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
}

public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[] {};
}
}

HttpsURLConnection conn = null;
            URL url = new URL(serviceUrl);
            conn = (HttpsURLConnection) url.openConnection();
             SSLContext sc = SSLContext.getInstance("SSL");  
             sc.init(null, new TrustManager[]{new TrustAnyTrustManager()}, new java.security.SecureRandom());  

             conn.setSSLSocketFactory(sc.getSocketFactory());
Sandip S.
la source
5
Ce code est totalement non sécurisé et ne doit pas être utilisé.
Marquis de Lorne
@ user207421 Pourquoi n'est-il pas sécurisé? Ce qui se passe brièvement dans le code.
Govinda Sakhare
Cela saute toutes les validations de certificat, fondamentalement, cela permet à tout certificat d'être accepté. La façon dont les certificats fonctionnent est qu'il existe un certificat racine (littéralement) physiquement protégé par diverses autorités de certification. Ce certificat est ensuite utilisé pour émettre d'autres certificats secondaires, qui peuvent être validés jusqu'à l'autorité de certification racine. Cela saute toutes les vérifications en amont, ce qui signifie que je peux envoyer n'importe quel certificat SSL (même auto-généré) et votre application l'acceptera comme sécurisé, même si mon identité en tant qu'URL n'est pas vérifiée.
Scott Taylor
4

J'utilisais jdk1.8.0_171 quand j'ai fait face au même problème. J'ai essayé les 2 meilleures solutions ici (en ajoutant un certificat en utilisant keytool et une autre solution qui a un hack), mais elles n'ont pas fonctionné pour moi.

J'ai amélioré mon JDK 1.8.0_181et cela a fonctionné comme un charme.

avp
la source
2

j'ai écrit un petit script stupide cm32 (ligne de commande) win32 (WinXP 32bit testet) qui recherche toutes les versions de java dans les fichiers programme et leur ajoute un certificat. Le mot de passe doit être le "changeit" par défaut ou le changer vous-même dans le script :-)

@echo off

for /F  %%d in ('dir /B %ProgramFiles%\java') do (
    %ProgramFiles%\Java\%%d\bin\keytool.exe -import -noprompt -trustcacerts -file some-exported-cert-saved-as.crt -keystore %ProgramFiles%\Java\%%d\lib\security\cacerts -storepass changeit
)

pause
mons droid
la source
2

Pour MacOS X ci-dessous, la commande exacte a fonctionné pour moi où j'ai dû essayer avec double hypen dans l'option 'importcert' qui fonctionnait:

sudo keytool -–importcert -file /PathTo/YourCertFileDownloadedFromBrowserLockIcon.crt -keystore /Library/Java/JavaVirtualMachines/jdk1.8.0_191.jdk/Contents/Home/jre/lib/security/cacerts -alias "Cert" -storepass changeit
Abhishek
la source
2

Pour moi, la solution reconnue de ce post n'a pas fonctionné: https://stackoverflow.com/a/9619478/4507034 .

Au lieu de cela, j'ai réussi à résoudre le problème en important la certification dans les certifications de confiance de ma machine.

Pas:

  1. Accédez à l'URL (par exemple https://localhost:8443/yourpath) où la certification ne fonctionne pas.
  2. Exportez la certification comme décrit dans l'article mentionné.
  3. Sur votre machine Windows ouverte: Manage computer certificates
  4. Allez à Trusted Root Certification Authorities->Certificates
  5. Importez ici votre your_certification_name.cerfichier.
Radu Linu
la source
1

Pour Tomcat fonctionnant sur le serveur Ubuntu, pour savoir quel Java est utilisé, utilisez la commande "ps -ef | grep tomcat":

Échantillon:

/home/mcp01$ **ps -ef |grep tomcat**
tomcat7  28477     1  0 10:59 ?        00:00:18 **/usr/local/java/jdk1.7.0_15/bin/java** -Djava.util.logging.config.file=/var/lib/tomcat7/conf/logging.properties -Djava.awt.headless=true -Xmx512m -XX:+UseConcMarkSweepGC -Djava.net.preferIPv4Stack=true -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Djava.endorsed.dirs=/usr/share/tomcat7/endorsed -classpath /usr/share/tomcat7/bin/bootstrap.jar:/usr/share/tomcat7/bin/tomcat-juli.jar -Dcatalina.base=/var/lib/tomcat7 -Dcatalina.home=/usr/share/tomcat7 -Djava.io.tmpdir=/tmp/tomcat7-tomcat7-tmp org.apache.catalina.startup.Bootstrap start
1005     28567 28131  0 11:34 pts/1    00:00:00 grep --color=auto tomcat

Ensuite, nous pouvons aller dans: cd /usr/local/java/jdk1.7.0_15/jre/lib/security

Le fichier cacerts par défaut se trouve ici. Insérez-y le certificat non approuvé.

oraclesoon
la source
1

pour des raisons de sécurité, nous ne devons pas utiliser de certificats auto-signés dans notre implémentation. Cependant, en ce qui concerne le développement, nous devons souvent utiliser des environnements d'essai avec des certificats auto-signés. J'ai essayé de résoudre ce problème par programme dans mon code et j'échoue. Cependant, en ajoutant le certificat au magasin de confiance jre, j'ai résolu mon problème. Veuillez trouver ci-dessous les étapes,

  1. Téléchargez le site cert,

  2. Copiez le certificat (ex: cert_file.cer) dans le répertoire $ JAVA_HOME \ Jre \ Lib \ Security

  3. Ouvrez CMD dans Administrateur et changez le répertoire en $ JAVA_HOME \ Jre \ Lib \ Security

  4. Importez le certificat dans un magasin de clés certifiées à l'aide de la commande ci-dessous,

keytool -import -alias ca -file cert_file.cer -keystore cacerts -storepass changeit

Si vous avez une erreur indiquant que keytool n'est pas reconnaissable, veuillez vous référer à ceci.

Tapez oui comme ci-dessous

Faites confiance à ce certificat: [Oui]

  1. Essayez maintenant d'exécuter votre code ou d'accéder à l'URL par programmation à l'aide de java.

Mise à jour

Si votre serveur d'applications est jboss, essayez d'ajouter la propriété système ci-dessous

System.setProperty("org.jboss.security.ignoreHttpsHost","true");

J'espère que cela t'aides!

tk_
la source
1

SOLUTION DÉPLOYABLE (Alpine Linux)

Pour pouvoir résoudre ce problème dans nos environnements d'application, nous avons préparé les commandes de terminal Linux comme suit:

cd ~

Générera un fichier cert dans le répertoire personnel.

apk add openssl

Cette commande installe openssl sous Linux alpin. Vous pouvez trouver des commandes appropriées pour d'autres distributions Linux.

openssl s_client -connect <host-dns-ssl-belongs> < /dev/null | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > public.crt

Généré le fichier cert nécessaire.

sudo $JAVA_HOME/bin/keytool -import -alias server_name -keystore $JAVA_HOME/lib/security/cacerts -file public.crt -storepass changeit -noprompt

Appliqué le fichier généré au JRE avec le programme 'keytool'.

Remarque: veuillez remplacer votre DNS par<host-dns-ssl-belongs>

Remarque 2: veuillez noter doucement que -nopromptle message de vérification ne sera pas invité (oui / non) et que le -storepass changeitparamètre désactivera l'invite de mot de passe et fournira le mot de passe requis (la valeur par défaut est 'changeit'). Ces deux propriétés vous permettront d'utiliser ces scripts dans vos environnements d'application comme la construction d'une image Docker.

Remarque3 Si vous déployez votre application via Docker, vous pouvez générer le fichier secret une fois et le placer dans vos fichiers de projet d'application. Vous n'aurez pas besoin de le générer encore et encore.

Bahadir Tasdemir
la source
0

J'ai aussi ce problème.

J'ai essayé presque tout en ajoutant le certificat SSL à .keystore, mais cela ne fonctionnait pas avec Java1_6_x. Pour moi, cela a aidé si nous commençons à utiliser une version plus récente de Java, Java1_8_x comme JVM.

nubien
la source
1
Pareil pour moi. Une mise à jour de Java 1.8.0_91 vers 1.8.0_121 a résolu le problème. J'ai eu l'exception en utilisant Apache HTTPClient.
Devabc
J'ai toujours ce problème en utilisant l'authentification Oauth2
Sofiane
0

J'avais ce problème avec Android Studio lorsque je suis derrière un proxy. J'utilisais Crashlytics qui essaie de télécharger le fichier de mappage lors d'une génération.

J'ai ajouté le certificat proxy manquant au magasin de confiance situé à l'adresse /Users/[username]/Documents/Android Studio.app/Contents/jre/jdk/Contents/Home/jre/lib/security/cacerts

avec la commande suivante: keytool -import -trustcacerts -keystore cacerts -storepass [password] -noprompt -alias [alias] -file [my_certificate_location]

par exemple avec le mot de passe truststore par défaut keytool -import -trustcacerts -keystore cacerts -storepass changeit -noprompt -alias myproxycert -file /Users/myname/Downloads/MyProxy.crt

Tourbillonnant
la source
0

Juste un petit hack. Mettez à jour l'URL dans le fichier "hudson.model.UpdateCenter.xml" de https à http

<?xml version='1.1' encoding='UTF-8'?>
<sites>
  <site>
    <id>default</id>
    <url>http://updates.jenkins.io/update-center.json</url>
  </site>
</sites>
Harshavardhan
la source
0

Je veux jouer car j'ai un environnement QEMU où je dois télécharger des fichiers en java. Il s'avère que /etc/ssl/certs/java/cacertsdans QEMU a un problème car il ne correspond pas au/etc/ssl/certs/java/cacerts à l'environnement hôte. L'environnement hôte est derrière un proxy d'entreprise, donc les cacerts java sont une version personnalisée.

Si vous utilisez un environnement QEMU, assurez-vous que le système hôte peut d'abord accéder aux fichiers. Par exemple, vous pouvez essayer ce script sur votre machine hôte. Si le script fonctionne très bien sur la machine hôte mais pas dans QEMU, alors vous rencontrez le même problème que moi.

Pour résoudre ce problème, j'ai dû faire une sauvegarde du fichier d'origine dans QEMU, copier le fichier dans l'environnement hôte vers la prison de chroot QEMU, puis java pouvait télécharger des fichiers normalement dans QEMU.

Une meilleure solution serait de monter le /etcdans l'environnement QEMU; cependant, je ne sais pas si d'autres fichiers seront impactés dans ce processus. J'ai donc décidé d'utiliser cette solution de contournement laide mais facile.

Roche
la source
0

Cela semble être un bon endroit pour documenter une autre raison possible du fameux message d'erreur PKIX. Après avoir passé beaucoup trop de temps à regarder le contenu du magasin de clés et du magasin de clés de confiance et diverses configurations d'installation Java, j'ai réalisé que mon problème était dû à ... une faute de frappe.

La faute de frappe signifiait que j'utilisais également le magasin de clés comme magasin de confiance. Comme l'autorité racine de mon entreprise n'était pas définie comme un certificat autonome dans le magasin de clés, mais uniquement comme faisant partie d'une chaîne de certificats, et n'était définie nulle part ailleurs (c.-à-d. Cacerts), je continuais à recevoir l'erreur PKIX.

Après une sortie ratée (c'est la config prod, c'était ok ailleurs) et deux jours de gratte tête j'ai enfin vu la faute de frappe, et maintenant tout va bien.

J'espère que cela aide quelqu'un.

Dave Richardson
la source
-1

ajoutez ceci à votre code:

TrustManager[] trustAllCerts = new TrustManager[]{
           new X509TrustManager() {
               @Override
               public java.security.cert.X509Certificate[] getAcceptedIssuers() {
                   return new X509Certificate[0];
               }

               @Override
               public void checkClientTrusted(
                       java.security.cert.X509Certificate[] certs, String authType) {
               }

               @Override
               public void checkServerTrusted(
                       java.security.cert.X509Certificate[] certs, String authType) {
               }
           }
       };

       try {
           SSLContext sc = SSLContext.getInstance("SSL");
           sc.init(null, trustAllCerts, new java.security.SecureRandom());
           HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
       } catch (GeneralSecurityException e) {
       }

la source
1
Les réponses uniquement codées sont généralement mal vues sur ce site. Pourriez-vous modifier votre réponse pour inclure des commentaires ou des explications sur votre code? Les explications devraient répondre à des questions telles que: Que fait-il? Comment ça marche? Où est-ce que ça va? Comment résout-il le problème d'OP?
mypetlion
1
ajoutez ceci à votre code . Ne l'ajoutez pas à votre code . La création d'un SSLContext de cette manière supprime tous les contrôles de sécurité qui vérifient l'identité du serveur auquel vous vous connectez. La réponse au problème de la perte de vos clés n'est PAS de supprimer tous les verrous de tout ce que vous possédez.
Andrew Henle