如何忽略javamail中的服务器证书错误

时间:2011-02-04 05:43:51

标签: java ssl javamail

当我使用imaps连接到我的imap服务器时,它很糟糕。

你能告诉我如何忽略javamail中的服务器证书错误

Exception in thread "main"
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:665)
    at javax.mail.Service.connect(Service.java:295)
    at javax.mail.Service.connect(Service.java:176)
    at App20110204.main(App20110204.java:31)
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 com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:174)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1623)
    at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Handshaker.java:198)
    at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Handshaker.java:192)
    at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1074)
    at com.sun.net.ssl.internal.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:128)
    at com.sun.net.ssl.internal.ssl.Handshaker.processLoop(Handshaker.java:529)
    at com.sun.net.ssl.internal.ssl.Handshaker.process_record(Handshaker.java:465)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:884)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1120)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1147)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1131)
    at com.sun.mail.util.SocketFetcher.configureSSLSocket(SocketFetcher.java:507)
    at com.sun.mail.util.SocketFetcher.getSocket(SocketFetcher.java:238)
    at com.sun.mail.iap.Protocol.<init>(Protocol.java:113)
    at com.sun.mail.imap.protocol.IMAPProtocol.<init>(IMAPProtocol.java:110)
    at com.sun.mail.imap.IMAPStore.protocolConnect(IMAPStore.java:632)
    ... 3 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:294)
    at sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:200)
    at sun.security.validator.Validator.validate(Validator.java:218)
    at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:126)
    at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:209)
    at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:249)
    at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1053)
    ... 15 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:174)
    at java.security.cert.CertPathBuilder.build(CertPathBuilder.java:238)
    at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:289)
    ... 21 more

和我的源代码

Properties prop = new Properties();
prop.put("mail.imap.ssl.checkserveridentity", "false");
prop.put("mail.imap.ssl.trust", "*");

Session session = Session.getDefaultInstance(prop);
Store store = session.getStore("imaps");
store.connect("mail.xxx.com", "xxxx", "p@ssw0rd");
System.out.println(store.getFolder("INBOX").getMessageCount());

10 个答案:

答案 0 :(得分:44)

使用prop.put("mail.imaps.ssl.trust", "*");,因为您使用的是imaps商店。

smtp您可以尝试:  prop.put("mail.smtp.ssl.trust", "*");

答案 1 :(得分:29)

不要忽略证书验证错误(除非可能在测试环境中):这违背了使用SSL / TLS的要点。

相反,如果您知道您信任该服务器证书,请将其导入您的信任存储区(例如,JRE的全局信任存储区或您使用javax.net.ssl.trustStore*系统属性指定的本地信任存储区)。

答案 2 :(得分:4)

如果您使用的是javamail 1.4.2+,则可以使用套接字工厂来忽略服务器证书。

MailSSLSocketFactory socketFactory= new MailSSLSocketFactory();
socketFactory.setTrustAllHosts(true);
prop.put("mail.imap.ssl.socketFactory", socketFactory);

答案 3 :(得分:4)

     Properties propsSSL = new Properties();
     propsSSL.put("mail.transport.protocol", "smtps");
     propsSSL.put("mail.smtps.host", "hostname");
     propsSSL.put("mail.smtps.auth", "true");
     propsSSL.put("mail.smtps.ssl.checkserveridentity", "false");
     propsSSL.put("mail.smtps.ssl.trust", "*");

以上更改将修复javax.mail.MessagingException: Could not connect to SMTP host: hostname, port: 465;嵌套异常

javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path validation failed: java.security.cert.CertPathValidatorException: Path does not chain with any of the trust anchors
exception 

答案 4 :(得分:2)

我认为@Bruno告诫你不要盲目信任所有服务器setTrustAllHosts(true)

docs at Oracle中,他们展示了如何将您的开发邮件主机添加到受信任列表,而不会强迫您的应用程序不安全地信任整个世界:

MailSSLSocketFactory sf = new MailSSLSocketFactory();
sf.setTrustedHosts(new String[] { "my-server" });
props.put("mail.smtp.ssl.enable", "true");
// also use following for additional safety
props.put("mail.smtp.ssl.checkserveridentity", "true");
props.put("mail.smtp.ssl.socketFactory", sf);

答案 5 :(得分:1)

我是同一个问题,使用

MailSSLSocketFactory socketFactory= new MailSSLSocketFactory();
socketFactory.setTrustAllHosts(true);
prop.put("mail.pop3s.ssl.socketFactory", socketFactory);

com.sun.mail.util.MailSSLSocketFactory

它的作品!!

答案 6 :(得分:1)

    Properties pr = new Properties();
    MailSSLSocketFactory socketFactory= new MailSSLSocketFactory();
    socketFactory.setTrustAllHosts(true);
    pr.put("mail.pop3s.ssl.socketFactory", socketFactory);
    Session ses = Session.getInstance(pr);
    ses.setDebug(true);
    URLName url =  new URLName("pop3s://username:password@host:posrt");
    Store store = ses.getStore(url.getProtocol());
    store.connect(url.getHost(), url.getPort(), url.getUsername(), url.getPassword());
    Folder inbox = store.getFolder("INBOX");
    inbox.open(Folder.READ_ONLY);
    try {
        int i = inbox.getMessageCount();
        com.sun.mail.pop3.POP3Message mes;
        while (i > 0) {
            mes = (com.sun.mail.pop3.POP3Message) inbox.getMessage(i);
            System.out.println(mes.getContentID());
            i--;
        }
    } finally {
        inbox.close(false);
        store.close();
    }

DEBUG:setDebug:JavaMail 1.4.5版 Exchange Server 2010
PlainTextLogin
http://technet.microsoft.com/ru-ru/library/bb124498(v=exchg.141).aspx

答案 7 :(得分:1)

如果问题持续存在于Java 6中,那么解决方案就很简单了。随着Java 7的发布,它就变得非常简单了。在机器java中安装java 7,使得证书文件具有忽略证书身份验证的能力。

复制&#34; cacerts&#34;来自以下java 7目录的文件

  

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

并将其粘贴到

  

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

现在将解决证书身份验证问题。

答案 8 :(得分:0)

这将帮助您绕过证书流程并直接转到ssl主机

MailSSLSocketFactory sf = null;
try
{
    sf = new MailSSLSocketFactory();
}
catch (GeneralSecurityException e)
{
    e.printStackTrace();
}
        sf.setTrustAllHosts(true);

Properties pop3Props = new Properties();
pop3Props.setProperty("mail.pop3.ssl.enable", "true");
pop3Props.setProperty("mail.protocol.ssl.trust", "pop3.live.com");
pop3Props.put("mail.pop3s.ssl.socketFactory", sf);
pop3Props.setProperty("mail.pop3s.port", "995");

Session session = Session.getInstance(pop3Props);

try
{
/* Get a Store object*/
   Store store = session.getStore("pop3s");
//process further activity 
}

答案 9 :(得分:0)

我是同一个问题。

  

MailSSLSocketFactory socketFactory = new MailSSLSocketFactory();   socketFactory.setTrustedHosts(new String [] {&#34; my-server&#34;});

     

socketFactory.setTrustAllHosts(真);   props.put(&#34; mail.smtps.socketFactory&#34;,socketFactory);

它的作品!!