简体   繁体   English

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

[英]Error in JavaMail : PKIX path building failed unable to find valid certification path to requested target

I am trying to build an email client app in android and right now i want to configure the javaMail part. 我正在尝试在android中构建一个电子邮件客户端应用程序,现在我想配置javaMail部分。

i am trying to establish the connection with the imap server but something is wrong with my code.. here is my code: 我正在尝试与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;
    }
}

I call the thread from another class like this 我从另一个类这样调用线程

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

I get the Following errors: 我收到以下错误:

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

i read something about PKIX path error that says to add the cert to java store as a trusted cert, but i dont know if this is the solution for this, and if it is i dont know how to do it. 我读了一些关于PKIX路径错误的说法,它将证书添加到java商店作为可信证书,但我不知道这是否是这个的解决方案,如果它是我不知道该怎么做。

// i dont have access to the mail server //我无权访问邮件服务器

Any suggestions? 有什么建议? thanks! 谢谢!

Ok problem solved! 好的问题解决了!

The solution is this: 解决方案是这样的:

First get the self-signed certificate from the mail server via openssl: 首先通过openssl从邮件服务器获取自签名证书:

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

Then save the yourcert.pem file into this path /Library/Java/Home/lib/security (on macOSX) and put the cert file into the cacerts like this 然后将yourcert.pem文件保存到此路径/ Library / Java / Home / lib / security(在macOSX上)并将cert文件放入这样的cacerts中

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

The default keystore password is changeit 默认密钥库密码是changeit

You can view the change that you made with this command that shows the Certificate fingerprint. 您可以使用此命令查看显示证书指纹的更改。

keytool -list -keystore cacerts

After this you should pass these argument in VM 在此之后,您应该在VM中传递这些参数

(for windows and linux type yourpath between " " ) (对于windows和linux,在“”之间键入你的路径)

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

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

For Debug: 对于调试:

-Djava.security.debug=certpath

-Djavax.net.debug=trustmanager

You can try upgrade library javax.mail.jar at https://java.net/projects/javamail/pages/Home (now version is 1.5.5) and add code : 您可以尝试在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);

This JavaMail FAQ entry should help. 此JavaMail FAQ条目应该有所帮助。

Quoted text from the linked site: 来自链接网站的引用文本:

Q: When connecting to my mail server over SSL I get an exception like "unable to find valid certification path to requested target". 问:当通过SSL连接到我的邮件服务器时,我得到一个例外,例如“无法找到所请求目标的有效证书路径”。

A: Your server is probably using a test certificate or self-signed certificate instead of a certificate signed by a commercial Certificate Authority. 答:您的服务器可能使用的是测试证书或自签名证书,而不是商业证书颁发机构签署的证书。 You'll need to install the server's certificate into your trust store. 您需要将服务器的证书安装到信任库中。 The InstallCert program will help. InstallCert程序将有所帮助。

Alternatively, you can set the "mail.protocol.ssl.trust" property to the host name of your mail server. 或者,您可以将“mail.protocol.ssl.trust”属性设置为邮件服务器的主机名。 See the javadocs for the protocol provider packages for details. 有关详细信息,请参阅协议提供程序包的javadocs。

Other common causes of this problem are: 此问题的其他常见原因是:

  • There's a firewall or anti-virus program intercepting your request. 有一个防火墙或反病毒程序拦截您的请求。
  • There's something wrong in your JDK installation preventing it from finding the certificates for the trusted certificate authorities. JDK安装中出现了问题,导致它无法找到受信任证书颁发机构的证书。
  • You're running in an application server that has overridden the JDK's list of trusted certificate authorities. 您正在一个已覆盖JDK的可信证书颁发机构列表的应用程序服务器中运行。

easy way to solve this problem by getiing certificate file from Java 7 通过从Java 7中获取证书文件来简化解决此问题的方法

copy the "cacerts" file from following java 7 directory 从以下java 7目录中复制“cacerts”文件

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

and paste it in java 6 directory 并将其粘贴到java 6目录中

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

I've lost so many days searching for a solution, and this post was helps to me. 我已经失去了很多天寻找解决方案,这篇文章对我很有帮助。 I had the same problem. 我有同样的问题。 I created a pem file like here, and then, the cert file .pem, was incrusted in cacert file (a copy called TrustStore.jks) with this command: 我在这里创建了一个pem文件,然后,使用以下命令在cacert文件(名为TrustStore.jks的副本)中嵌入了cert文件.pem:

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

(DOMAINNAME must be replace by hostname -this trick is very important-, and MYCERTFILE by file recent create...) (DOMAINNAME必须替换为主机名 - 这个技巧非常重要 - 而且MYCERTFILE按文件最近创建...)

I hope that this solution can helps to somebody. 我希望这个解决方案可以帮助某人。

I also have run across this problem when talking to a mail server. 与邮件服务器通信时,我也遇到过这个问题。 However, the root cause was that the server (Exchange 2013) had both a real certificate AND a self-signed applied to it. 但是,根本原因是服务器(Exchange 2013)具有真实证书和应用于其的自签名。 The appropriate course of action was to remove the self-signed on the server because it was taking precedence and blocking the real certificate. 适当的操作方法是删除服务器上的自签名,因为它优先并阻止真实证书。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Maven 错误,PKIX 路径构建失败:无法找到到请求目标的有效认证路径 - Maven error, PKIX path building failed: unable to find valid certification path to requested target 获取错误:PKIX 路径构建失败:无法找到请求目标的有效认证路径 - Getting error: PKIX path building failed: unable to find valid certification path to requested target PKIX路径构建失败:无法找到请求的目标的有效证书路径-导入的CERT - PKIX path building failed: unable to find valid certification path to requested target - imported CERT “PKIX 路径构建失败 - 无法找到请求目标的有效认证路径”(在具有身份验证的公司代理后面) - 'PKIX path building failed - unable to find valid certification path to requested target' (behind corporate proxy with authenthication) “PKIX 路径构建失败:无法找到请求目标的有效证书路径”使用 java.net HttpClient - "PKIX path building failed: unable to find valid certification path to requested target" using java.net HttpClient javax.mail.MessagingException:PKIX 路径构建失败:SunCertPathBuilderException:无法找到请求目标的有效证书路径; - javax.mail.MessagingException: PKIX path building failed: SunCertPathBuilderException: unable to find valid certification path to requested target; sun.security.validator.ValidatorException:PKIX路径构建失败:无法找到到请求目标的有效证书路径 - sun.security.validator.ValidatorException: PKIX path building failed: unable to find valid certification path to requested target PKIX 路径构建失败:SunCertPathBuilderException:无法找到到请求目标的有效认证路径 - PKIX path building failed: SunCertPathBuilderException: unable to find valid certification path to requested target Java-PKIX路径构建失败:无法找到到请求目标的有效证书路径 - Java - PKIX path building failed: unable to find valid certification path to requested target PKIX 路径构建失败:无法找到到请求目标的有效证书路径 - PKIX path building failed: unable to find valid certification path to requested target
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM