JavaMail中的错误:PKIX路径构建失败,无法找到所请求目标的有效证书路径

我正在尝试在android中构建一个电子邮件客户端应用程序,现在我想配置javaMail部分。

我正在尝试与imap服务器建立连接但我的代码有问题..这是我的代码:

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; } } 

我从另一个类这样调用线程

 connec=new Connection(); (new Thread(connec)).start(); 

我收到以下错误:

 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.(Response.java:96) at com.sun.mail.imap.protocol.IMAPResponse.(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.(Protocol.java:114) at com.sun.mail.imap.protocol.IMAPProtocol.(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 

我读了一些关于PKIX路径错误的说法,它将证书添加到java商店作为可信证书,但我不知道这是否是这个的解决方案,如果是我不知道该怎么做。

//我无法访问邮件服务器

有什么建议么? 谢谢!

好的问题解决了!

解决方案是这样的:

首先通过openssl从邮件服务器获取自签名证书:

 echo | openssl s_client -connect yoursever:port 2>&1 | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > yourcert.pem 

然后将yourcert.pem文件保存到此路径/ Library / Java / Home / lib / security(在macOSX上),并将cert文件放入cacerts中,如下所示

 keytool -keystore cacerts -importcert -alias youralias -file yourcert.pem 

默认密钥库密码是changeit

您可以使用此命令查看显示证书指纹的更改。

keytool -list -keystore cacerts

在此之后,您应该在VM中传递这些参数

(对于windows和linux,在“”之间输入你的路径)

-Djavax.net.ssl.trustStore="/Library/Java/Home/lib/security/cacerts"

-Djavax.net.ssl.trustStorePassword="changeit"

对于调试:

-Djava.security.debug=certpath

-Djavax.net.debug=trustmanager

您可以尝试在https://java.net/projects/javamail/pages/Home (现在的版本是1.5.5)上升级库javax.mail.jar并添加代码:

 MailSSLSocketFactory sf = new MailSSLSocketFactory(); sf.setTrustAllHosts(true); properties.put("mail.imap.ssl.trust", "*"); properties.put("mail.imap.ssl.socketFactory", sf); 

通过从Java 7中获取证书文件来解决此问题的简便方法

从以下java 7目录中复制“cacerts”文件

 C:\Program Files\Java\jdk1.7.0_79\jre\lib\security 

并将其粘贴到java 6目录中

 C:\Program Files\Java\jdk1.6.0\jre\lib\security 

此JavaMail FAQ条目应该有所帮助。

来自链接网站的引用文本:

问:当通过SSL连接到我的邮件服务器时,我得到一个例外,例如“无法找到所请求目标的有效证书路径”。

答:您的服务器可能使用的是测试证书或自签名证书,而不是商业证书颁发机构签署的证书。 您需要将服务器的证书安装到信任库中。 InstallCert程序将有所帮助。

或者,您可以将“mail.protocol.ssl.trust”属性设置为邮件服务器的主机名。 有关详细信息,请参阅协议提供程序包的javadocs。

此问题的其他常见原因是:

  • 有一个防火墙或防病毒程序拦截您的请求。
  • 您的JDK安装有问题,导致它无法找到可信证书颁发机构的证书。
  • 您正在一个已覆盖JDK的可信证书颁发机构列表的应用程序服务器中运行。

我已经失去了很多天寻找解决方案,这篇文章对我很有帮助。 我有同样的问题。 我在这里创建了一个pem文件,然后使用以下命令在cacert文件(名为TrustStore.jks的副本)中嵌入了cert文件.pem:

keytool.exe -import -noprompt -keystore TrustStore.jks -storepass changeit ^ -alias DOMAINNAME -file MYCERTFILE.pem

(DOMAINNAME必须替换为主机名 – 这个技巧非常重要 – 而且MYCERTFILE按文件最近创建…)

我希望这个解决方案可以帮助某人。

在与邮件服务器通信时,我也遇到过这个问题。 但是,根本原因是服务器(Exchange 2013)具有真实证书和应用于其的自签名。 适当的操作方法是删除服务器上的自签名,因为它优先并阻止真实证书。