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

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

smtp凭据已通过telnetting到我的smtpHost进行validation,并提供上述详细信息。 但是,当我在java邮件中使用上述设置时,我得到以下exception。

  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 

当我添加该行时:

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

它再次生成相同的身份validation失败exception。

如果我将mail.smtp.starttls.enable设置为true ,则身份validation成功,但是我收到以下exception:

  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) 

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

  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 

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

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

尝试使用这样的MailSSLSocketFactory:

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

为我工作:)

 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("mail@companydomain.biz", "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( "mail@companydomain.biz" ) ); } 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("myemailid@companydomain.biz") ); } 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(); } } 

我用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 

我认为这会有所帮助。