Erreur dans JavaMail : PKIX chemin d'accès du bâtiment a échoué impossible de trouver le chemin de certification valide à la demande de la cible
Je suis en train de construire un client de messagerie app android, et maintenant je veux configurer le javaMail partie.
que j'essaie d'établir la connexion avec le serveur imap mais quelque chose de mal avec mon code..
voici mon code:
package mailpackage;
import java.util.Properties;
import javax.mail.Folder;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.NoSuchProviderException;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Store;
public class Connection implements Runnable
{
boolean done;
public Connection()
{
this.done=false;
}
@Override
public void run()
{
System.out.println("Hello from Connection Thread!");
while(!done)
{
String host = "myhost";//change accordingly
String mailStoreType = "imap";
String username = "myusername";//change accordingly
String password = "mypasswd";//change accordingly
check(host, mailStoreType, username, password);
}
}
public static void receiveEmail(String host, String storeType, String username, String password)
{
try
{
Properties properties = new Properties();
properties.put("mail.imap.com", host);
properties.put("mail.imap.starttls.enable","true");
properties.put("mail.imap.auth", "true"); //If you need to authenticate
//Use the following if you need SSL
properties.put("mail.imap.socketFactory.port", 993);
properties.put("mail.imap.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
properties.put("mail.imap.socketFactory.fallback", "false");
Session emailSession = Session.getDefaultInstance(properties);
emailSession.setDebug(true);
//2) create the IMAP store object and connect with the Imap server
IMAPStore emailStore = (IMAPStore) emailSession.getStore(storeType);
emailStore.connect(host, username, password);
//3) create the folder object and open it
Folder emailFolder = emailStore.getFolder("INBOX");
emailFolder.open(Folder.READ_ONLY);
//4) retrieve the messages from the folder in an array and print it
Message[] messages = emailFolder.getMessages();
for (int i = 0; i <messages.length; i++)
{
Message message = messages[i];
MimeMessage m = new MimeMessage(emailSession);
m.setContent(((MimeMessage)messages[i]).getContent() , "text/plain; charset=UTF-8");
System.out.println("---------------------------------");
System.out.println("Email Number " + (i + 1));
System.out.println("Subject: " + message.getSubject());
System.out.println("From: " + message.getFrom()[0]);
System.out.println("Text: " + message.getContent().toString());
m.writeTo(System.out);
}
//5) close the store and folder objects
emailFolder.close(false);
emailStore.close();
}
catch (NoSuchProviderException e) {e.printStackTrace();}
catch (MessagingException e) {e.printStackTrace();}
catch (IOException e) {e.printStackTrace();}
}
public void stopThread()
{
this.done=true;
}
}
J'appelle le fil d'une autre classe, comme ce
connec=new Connection();
(new Thread(connec)).start();
J'obtiens les erreurs Suivantes:
javax.mail.MessagingException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target;
nested exception is:
javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at com.sun.mail.imap.IMAPStore.protocolConnect(IMAPStore.java:571)
at javax.mail.Service.connect(Service.java:288)
at javax.mail.Service.connect(Service.java:169)
at mailpackage.Connection.check(Connection.java:63)
at mailpackage.Connection.run(Connection.java:33)
at java.lang.Thread.run(Thread.java:744)
Caused by: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at sun.security.ssl.Alerts.getSSLException(Alerts.java:192)
at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1884)
at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:276)
at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:270)
at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1341)
at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:153)
at sun.security.ssl.Handshaker.processLoop(Handshaker.java:868)
at sun.security.ssl.Handshaker.process_record(Handshaker.java:804)
at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1016)
at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1312)
at sun.security.ssl.SSLSocketImpl.readDataRecord(SSLSocketImpl.java:882)
at sun.security.ssl.AppInputStream.read(AppInputStream.java:102)
at com.sun.mail.util.TraceInputStream.read(TraceInputStream.java:110)
at java.io.BufferedInputStream.fill(BufferedInputStream.java:235)
at java.io.BufferedInputStream.read(BufferedInputStream.java:254)
at com.sun.mail.iap.ResponseInputStream.readResponse(ResponseInputStream.java:98)
at com.sun.mail.iap.Response.<init>(Response.java:96)
at com.sun.mail.imap.protocol.IMAPResponse.<init>(IMAPResponse.java:61)
at com.sun.mail.imap.protocol.IMAPResponse.readResponse(IMAPResponse.java:135)
at com.sun.mail.imap.protocol.IMAPProtocol.readResponse(IMAPProtocol.java:261)
at com.sun.mail.iap.Protocol.<init>(Protocol.java:114)
at com.sun.mail.imap.protocol.IMAPProtocol.<init>(IMAPProtocol.java:104)
at com.sun.mail.imap.IMAPStore.protocolConnect(IMAPStore.java:538)
... 5 more
Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:385)
at sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:292)
at sun.security.validator.Validator.validate(Validator.java:260)
at sun.security.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:326)
at sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:231)
at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:126)
at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1323)
... 23 more
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:196)
at java.security.cert.CertPathBuilder.build(CertPathBuilder.java:268)
at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:380)
... 29 more
j'ai lu quelque chose à propos de PKIX chemin erreur qui dit que pour ajouter le cert de java magasin de confiance cert, mais je ne sais pas si c'est la solution pour ce faire, et si elle est, je ne sais pas comment le faire.
//je n'ai pas accès au serveur de messagerie
Des suggestions? merci!
- J'ai couru dans cet après l'installation de Avast anti-virus. J'ai trouvé 2 solutions: 1. désactiver l'analyse SSL dans avast, 2. ajouter votre hôte pour "le courrier.smtp.le protocole ssl.confiance" dans votre java mail config. Je suis sûr que ni l'approche recommandée, mais ils sont certainement la meilleure des options.
- Le problème est que Sun/Oracle met en œuvre sa propre manière de gérer les certificats et il n'y a aucun moyen de spécifier que vous ne souhaitez pas que mais vous voulez utiliser, par exemple, openSSL ou l'implémentation par défaut de votre système d'exploitation. C'est un problème de conception ou vous pourriez même envisager un bug.
Vous devez vous connecter pour publier un commentaire.
Ok problème résolu!
La solution est: est-ce
De la première à obtenir le certificat auto-signé à partir du serveur de messagerie via openssl:
Puis enregistrez le yourcert.fichier pem dans ce chemin d'accès /Library/Java/Home/lib/security (sur macOSX) et de mettre le cert fichier dans le fichier cacerts comme ce
Le stockage par défaut le mot de passe est changeit
Vous pouvez voir le changement que vous avez fait avec cette commande, qui montre le Certificat d'empreintes digitales.
keytool -list -keystore cacerts
Après cela, vous devez passer ces argument en VM
(pour windows et linux type yourpath entre "" )
-Djavax.net.ssl.trustStore="/Library/Java/Home/lib/security/cacerts"
-Djavax.net.ssl.trustStorePassword="changeit"
Pour Debug:
-Djava.security.debug=certpath
-Djavax.net.debug=trustmanager
Vous pouvez essayer la mise à niveau de la bibliothèque javax.mail.jar au https://java.net/projects/javamail/pages/Home (maintenant la version 1.5.5) et ajoutez le code :
imap
avecimaps
dans les valeurs de propriété à faire ce travail, mais vous avez ma upvote. Toutefois, cela ne devrait être fait pour les tests! Permettre à l'utilisateur de décider s'ils confiance au serveur, puis ajouter le serveur à la liste d'hôtes de confiance (je ne sais pas encore comment faire. Quand je le fais, je vais poster une réponse)une façon simple de résoudre ce problème par getiing fichier de certificat à partir de Java 7
copiez le fichier cacerts" fichier à partir de java 7 répertoire
et de le coller dans la version 6 de java répertoire
Cette JavaMail entrée de la FAQ devrait aider.
Texte cité à partir du site lié:
echo | openssl s_client -connect server:port 2>&1 | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > cert.pem
et j'ai enregistrer le fichier cert.pem. Ensuite, j'ai sauvé le cert.fichier pem dans ce chemin d'accès /Library/Java/Home/lib/security et j'ai mis le cert fichier dans le fichier cacerts comme cekeytool -keystore cacerts -importcert -alias myalias -file cert.pem
puis-je exécuter l'application et j'obtiens les mêmes erreurs. Toutes les pensées?keytool -list -keystore cacerts
keytool montre le Certificat d'empreintes digitales (SHA1). Oui, l'application s'exécute sur la même machine. Sur le JDK et JRE terminal ditjavac version 1.7.0_45
donc je ne pense pas qu'il y a installé des autres versions. J'utilise Eclipse IDE pour exécuter l'application. Si j'utilise ces options de débogage, je reçois beaucoup de l'info..j'ai remarqué que lesubject DNS dont match
etcerts dont match
..je vais essayer de supprimer le cert et la saisir à nouveau parce que j'ai importé dans cacert plus d'une fois. merci pour l'aide, le lien a été très utile!-Djavax.net.debug=all
) j'ai vu le texte "Subject: CN=AVG Web/Mail Shield Root, O=AVG Web/Mail Shield, OU=generated by AVG Antivirus for SSL/TLS scanning
" en cours d'impression. Après la désactivation de AVG tout fonctionne comme prévu.J'ai perdu beaucoup de jours à chercher une solution, et ce poste était une aide pour moi. J'ai eu le même problème. J'ai créé un fichier pem comme ici, et puis, le cert fichier .pem, a été incrusté dans le fichier cacert (une copie appelée TrustStore.jks) avec cette commande:
keytool.exe -import-noprompt -keystore TrustStore.jks -storepass changeit ^ -alias de NOM de fichier MYCERTFILE.pem
(Nom de DOMAINE doit être remplacer par le nom d'hôte -cette astuce est très important-, et MYCERTFILE par fichier récente créer...)
J'espère que cette solution vous aide à quelqu'un.
J'ai aussi couru à travers ce problème lorsque l'on parle à un serveur de messagerie. Cependant, la cause était que le serveur (Exchange 2013) avait à la fois un réel ET d'un certificat auto-signé est appliqué. Le cours de l'action était de supprimer l'auto-signé sur le serveur, car il a été donné la priorité à la et le blocage de la véritable certificat.