问题
I am using java mail to send emails over smtp. The smtp settings given below:
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.
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.enable to true, the authentication succeeds, but I get the following 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)
After going through various forum threads regarding the second exception, I ran the InstallCert program to fetch the server's self-signed certificate. The InstallCert throws the following 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
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?
回答1:
This JavaMail FAQ entry should help.
Try using MailSSLSocketFactory like this:
MailSSLSocketFactory sf = new MailSSLSocketFactory();
sf.setTrustAllHosts(true);
props.put("mail.smtp.ssl.socketFactory", sf);
回答2:
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("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();
}
}
回答3:
I had this problem with java 8. After updating this property problem solved
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.
来源:https://stackoverflow.com/questions/13599234/java-mail-without-ssl-pkix-path-building-failed