【问题标题】:how to ignore server cert error in javamail如何忽略javamail中的服务器证书错误
【发布时间】:2011-06-21 03:57:53
【问题描述】:

当我使用 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());

【问题讨论】:

标签: java ssl jakarta-mail


【解决方案1】:

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

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

【讨论】:

  • 使用 mail.imaps.ssl.trust 为我修复了它,奇怪的是文档(我已经阅读过)只提到了 mail.imap.ssl.trust 而从未提到过 mail.imaps.ssl。信任或任何其他财产 mail.imaps.xxx 就此事。我假设在使用 starttls 而不是 SSL 隧道时使用 mail.imap.ssl.trust。
【解决方案2】:

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

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

【讨论】:

  • 如果您愿意信任所有主机,为什么还要使用 SSL...不要在生产中使用它。
  • 我同意我们永远不应该在生产中使用它。这通常用于自签名证书。我在连接到使用自签名证书的测试 imaps 服务器时遇到了同样的问题。这为我解决了问题。
  • 谢谢,作为功能测试框架的一部分,我需要它通过 IMAP 连接到 Gmail。
  • @Bruno 这不如正确信任特定证书安全,并且容易受到 MITM 攻击,但仍然相对比完全不加密更安全。我会说使用mail.imaps.ssl.trustmail.smtp.ssl.trust 信任特定 主机比这更好。
【解决方案3】:

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

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

【讨论】:

  • 啊,StackOverflow:安全问题的安全答案被否决,不安全的答案被投赞成票。叹息....
  • 这是一个很好的答案。如果您使用第三方代码怎么办?您不能使用其他答案中提出的任何肮脏的技巧。这个可行,但它可能更具体地说明如何添加证书。对此有帮助的是,我意识到我必须更改 jre/lib/security/cacerts,使用以下建议:martin-probst.com/blog/2008/03/14/… 简而言之:使用 keytool -import -file your_cert.cer /path/to/cacerts,密码是 changeit。跨度>
  • 鉴于第 3 方商业单根 CA 的限制,除了只有您自己的 CA 的信任存储之外,任何东西都不完整。重点是,对于客户端需要远程端点的多租户 Web 应用程序,无论他们是否为商业证书付费,MITM 风险通常被认为对于定义明确的端点是可以接受的。
【解决方案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 

【讨论】:

    【解决方案5】:

    我也是同样的问题,使用

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

    com.sun.mail.util.MailSSLSocketFactory

    成功了!!

    【讨论】:

      【解决方案6】:
          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();
          }
      

      调试:setDebug:JavaMail 版本 1.4.5
      Exchange server 2010
      纯文本登录
      http://technet.microsoft.com/ru-ru/library/bb124498(v=exchg.141).aspx

      【讨论】:

        【解决方案7】:

        这将帮助您绕过证书过程并直接访问 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 
        }
        

        【讨论】:

          【解决方案8】:

          我认为@Bruno 告诫您不要盲目信任所有具有 hack 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);
          

          【讨论】:

          • 我认为对于知名且受信任的服务器而言,这是最安全的解决方案
          【解决方案9】:

          我也是同样的问题。

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

          socketFactory.setTrustAllHosts(true); props.put("mail.smtps.socketFactory", socketFactory);

          成功了!!

          【讨论】:

            【解决方案10】:

            如果是Java 6中仍然存在的问题,那么解决方法很简单。就像Java 7发布一样简单。在机器中安装java 7。java 7具有证书文件,具有忽略证书身份验证的能力。

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

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

            并粘贴到

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

            现在证书认证问题将得到解决。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2021-08-16
              • 2019-09-05
              • 1970-01-01
              • 2014-06-08
              • 1970-01-01
              相关资源
              最近更新 更多