没有 ssl 的 Java 邮件 - PKIX 路径构建失败:

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/13599234/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 13:22:09  来源:igfitidea点击:

Java mail without ssl - PKIX path building failed:

javasmtpjavamailstarttls

提问by janenz00

I am using java mail to send emails over smtp. The smtp settings given below:

我正在使用 java 邮件通过 smtp 发送电子邮件。下面给出的 smtp 设置:

        Properties props = new Properties();
        Object put = props.put("mail.smtp.host", smtpHost);
        props.put("mail.smtp.user", smtpUser);
        props.put("mail.smtp.auth", true);
        props.put("mail.debug", mailDebug);
        props.put("mail.smtp.port", port);

The smtp credentials have been verified by telnetting to my smtpHost with the above details. However, I get the following exception when I use the above settings in java mail.

smtp 凭据已通过 telnet 连接到我的 smtpHost 并使用上述详细信息进行验证。但是,当我在 java 邮件中使用上述设置时,出现以下异常。

        250-AUTH PLAIN LOGIN
        250-STARTTLS
        250 HELP
        DEBUG SMTP: Found extension "SIZE", arg "52428800"
        DEBUG SMTP: Found extension "8BITMIME", arg ""
        DEBUG SMTP: Found extension "PIPELINING", arg ""
        DEBUG SMTP: Found extension "AUTH", arg "PLAIN LOGIN"
        DEBUG SMTP: Found extension "STARTTLS", arg ""
        DEBUG SMTP: Found extension "HELP", arg ""
        DEBUG SMTP: Attempt to authenticate
        DEBUG SMTP: check mechanisms: LOGIN PLAIN DIGEST-MD5 NTLM
        DEBUG SMTP: AUTH LOGIN command trace suppressed
        DEBUG SMTP: AUTH LOGIN failed
        Nov 29, 2012 11:54:40 AM com.Test main
        SEVERE: null
        javax.mail.AuthenticationFailedException: 535 Incorrect authentication data

When I add the line :

当我添加行时:

        props.put("mail.smtp.starttls.enable", false);

It again generates the same authentication failed exception.

它再次生成相同的身份验证失败异常。

If I set mail.smtp.starttls.enableto true, the authentication succeeds, but I get the following exception:

如果我将mail.smtp.starttls.enable设置为true,则身份验证成功,但出现以下异常:

     220 TLS go ahead
     Nov 28, 2012 5:32:36 PM com.Test main
     SEVERE: null
     javax.mail.MessagingException: Could not convert socket to TLS;
     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.smtp.SMTPTransport.startTLS(SMTPTransport.java:1918)
    at com.sun.mail.smtp.SMTPTransport.protocolConnect(SMTPTransport.java:652)
    at javax.mail.Service.connect(Service.java:317)

After going through various forum threads regarding the second exception, I ran the InstallCert program to fetch the server's self-signed certificate. The InstallCertthrows the following exception:

在浏览了关于第二个异常的各种论坛帖子后,我运行了 InstallCert 程序来获取服务器的自签名证书。该InstallCert抛出以下异常:

            Opening connection to mydomain.com.au:443...
            Starting SSL handshake...
            javax.net.ssl.SSLException: Unrecognized SSL message, plaintext connection?
                    at sun.security.ssl.InputRecord.handleUnknownRecord(InputRecord.java:542)
                    at sun.security.ssl.InputRecord.read(InputRecord.java:374)
                    at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:850)
                    at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1190)
                    at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1217)
                    at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1201)
                    at InstallCert.main(InstallCert.java:100)
            Could not obtain server certificate chain

So, looks like my server does not have ssl, but starttls is enabled. What are the correct parameters for sending mail with STARTTLS on, to a server with no ssl?

所以,看起来我的服务器没有 ssl,但启用了 starttls。将带有 STARTTLS 的邮件发送到没有 ssl 的服务器的正确参数是什么?

回答by Bill Shannon

This JavaMail FAQ entryshould help.

这个 JavaMail FAQ 条目应该会有所帮助。

Try using MailSSLSocketFactory like this:

尝试像这样使用 MailSSLSocketFactory:

  MailSSLSocketFactory sf = new MailSSLSocketFactory();
  sf.setTrustAllHosts(true);
  props.put("mail.smtp.ssl.socketFactory", sf);

回答by Danyal Sandeelo

Worked for me :)

对我来说有效 :)

Properties props = new Properties();
        props.put("mail.transport.protocol", "smtp");
        props.put("mail.smtp.host", "smtp.companydomain.biz"); // 
        props.put("mail.smtp.auth", "true");
        props.put("mail.debug", "true"); 
        props.put("mail.smtp.starttls.enable", "true");`enter code here`
        props.put("mail.smtp.port", "25");
        props.put("mail.smtp.socketFactory.port", "25");
        props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
        props.put("mail.smtp.socketFactory.fallback", "true");

        MailSSLSocketFactory sf = null;
        try {
            sf = new MailSSLSocketFactory();
        } catch (GeneralSecurityException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }
        sf.setTrustAllHosts(true);
        props.put("mail.smtp.ssl.socketFactory", sf);

        Session mailSession = Session.getInstance(props, new javax.mail.Authenticator() {

            protected PasswordAuthentication getPasswordAuthentication() {
                return new PasswordAuthentication("[email protected]", "password");
            }
        });

        mailSession.setDebug(true); // Enable the debug mode

        Message msg = new MimeMessage( mailSession );

        //--[ Set the FROM, TO, DATE and SUBJECT fields
        try {
            msg.setFrom( new InternetAddress( "[email protected]" ) );
        } catch (AddressException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (MessagingException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        try {
            msg.setRecipients( Message.RecipientType.TO,InternetAddress.parse("[email protected]") );
        } catch (AddressException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (MessagingException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        //msg.setSentDate(new Date());
        try {
            msg.setSubject( "Hello World!" );
        } catch (MessagingException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        //--[ Create the body of the mail
        try {
            msg.setText( "Hello from my first e-mail sent with JavaMail" );
        } catch (MessagingException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        //--[ Ask the Transport class to send our mail message
        try {
            Transport.send( msg );
        } catch (MessagingException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }   
    }

回答by Asanka

I had this problem with java 8. After updating this property problem solved

我在 java 8 上遇到了这个问题。更新这个属性后问题解决了

props.put("mail.smtp.ssl.trust", "smtp.gmail.com")

if used spring boot in application.property

spring.mail.properties.mail.smtp.ssl.trust = smtp.gmail.com

I think this will help.

我认为这会有所帮助。