Secure SMTP connection with TLS/SSL issue and solution

Han Truong
3 min readJan 5, 2021

--

There are 2 ways to use SSL certificate to secure connection in Java:

  1. Import certificate to cacerts, usually located at $JAVA_HOME/jre/lib/security/cacerts
keytool -import -keystore cacerts -file cert.cer -nopromptC:\HanTruong>"C:\Program Files\Zulu\zulu-8\bin\keytool" -import -keystore cacerts -file cert.cer -noprompt
Enter keystore password:
Re-enter new password:
Certificate was added to keystore

2. Use the cacerts in Java code by adding it into System properties

static {
Properties pros = System.getProperties();
pros.put("javax.net.ssl.trustStore", <trustStore file location>);
pros.put("javax.net.ssl.trustStorePassword", <keyStorePassword>);
}
email.setStartTLSEnabled(true);
email.setStartTLSRequired(true);
email.setSslSmtpPort("SMTP SSL PORT");
email.setSSLCheckServerIdentity(true);
email.setSSLOnConnect(true);
email.getMailSession().getProperties().setProperty("mail.smtp.socketFactory.fallback", "true");

If we would like to enable SSL secure connection without using certificate or wrong configuration, you might get these exceptions. These issues might happen often when people use TLS/SSL connection with SMTP port 25.

Caused by: javax.mail.MessagingException: Could not connect to SMTP host: xxx.xxx.xxx.xxx, port: 25;
nested exception is:
javax.net.ssl.SSLException: Unsupported or unrecognized SSL message
at com.sun.mail.smtp.SMTPTransport.openServer(SMTPTransport.java:2120)
at com.sun.mail.smtp.SMTPTransport.protocolConnect(SMTPTransport.java:712)
at javax.mail.Service.connect(Service.java:366)
at javax.mail.Service.connect(Service.java:246)
at javax.mail.Service.connect(Service.java:195)
at javax.mail.Transport.send0(Transport.java:254)
at javax.mail.Transport.send(Transport.java:124)
at org.apache.commons.mail.Email.sendMimeMessage(Email.java:1459)
... 4 more
Caused by: javax.net.ssl.SSLException: Unsupported or unrecognized SSL message
at sun.security.ssl.SSLSocketInputRecord.handleUnknownRecord(SSLSocketInputRecord.java:449)
at sun.security.ssl.SSLSocketInputRecord.decode(SSLSocketInputRecord.java:175)
at sun.security.ssl.SSLTransport.decode(SSLTransport.java:110)
at sun.security.ssl.SSLSocketImpl.decode(SSLSocketImpl.java:1202)
at sun.security.ssl.SSLSocketImpl.readHandshakeRecord(SSLSocketImpl.java:1111)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:398)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:370)
at com.sun.mail.util.SocketFetcher.configureSSLSocket(SocketFetcher.java:598)
at com.sun.mail.util.SocketFetcher.createSocket(SocketFetcher.java:372)
at com.sun.mail.util.SocketFetcher.getSocket(SocketFetcher.java:217)
at com.sun.mail.smtp.SMTPTransport.openServer(SMTPTransport.java:2084)
Caused by: javax.mail.MessagingException: Could not convert socket to TLS
at com.sun.mail.smtp.SMTPTransport.startTLS(SMTPTransport.java:2064) ~[javax.mail-1.5.6.jar:1.5.6]
at com.sun.mail.smtp.SMTPTransport.protocolConnect(SMTPTransport.java:724) ~[javax.mail-1.5.6.jar:1.5.6]
at javax.mail.Service.connect(Service.java:366) ~[javax.mail-1.5.6.jar:1.5.6]
at javax.mail.Service.connect(Service.java:246) ~[javax.mail-1.5.6.jar:1.5.6]
at javax.mail.Service.connect(Service.java:195) ~[javax.mail-1.5.6.jar:1.5.6]
at javax.mail.Transport.send0(Transport.java:254) ~[javax.mail-1.5.6.jar:1.5.6]
at javax.mail.Transport.send(Transport.java:124) ~[javax.mail-1.5.6.jar:1.5.6]
at org.apache.commons.mail.Email.sendMimeMessage(Email.java:1459) ~[commons-email-1.5.jar:1.5]
... 4 more
Caused by: javax.net.ssl.SSLException: Unexpected error: java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty
at sun.security.ssl.Alert.createSSLException(Alert.java:133) ~[?:1.8.0_272]
at sun.security.ssl.TransportContext.fatal(TransportContext.java:348) ~[?:1.8.0_272]
at sun.security.ssl.TransportContext.fatal(TransportContext.java:291) ~[?:1.8.0_272]
at sun.security.ssl.TransportContext.fatal(TransportContext.java:286) ~[?:1.8.0_272]
at sun.security.ssl.SSLSocketImpl.handleException(SSLSocketImpl.java:1362) ~[?:1.8.0_272]
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:411) ~[?:1.8.0_272]
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:370) ~[?:1.8.0_272]
at com.sun.mail.util.SocketFetcher.configureSSLSocket(SocketFetcher.java:598) ~[javax.mail-1.5.6.jar:1.5.6]
at com.sun.mail.util.SocketFetcher.startTLS(SocketFetcher.java:525) ~[javax.mail-1.5.6.jar:1.5.6]
at com.sun.mail.smtp.SMTPTransport.startTLS(SMTPTransport.java:2059) ~[javax.mail-1.5.6.jar:1.5.6]
at com.sun.mail.smtp.SMTPTransport.protocolConnect(SMTPTransport.java:724) ~[javax.mail-1.5.6.jar:1.5.6]
at javax.mail.Service.connect(Service.java:366) ~[javax.mail-1.5.6.jar:1.5.6]
at javax.mail.Service.connect(Service.java:246) ~[javax.mail-1.5.6.jar:1.5.6]
at javax.mail.Service.connect(Service.java:195) ~[javax.mail-1.5.6.jar:1.5.6]
at javax.mail.Transport.send0(Transport.java:254) ~[javax.mail-1.5.6.jar:1.5.6]
at javax.mail.Transport.send(Transport.java:124) ~[javax.mail-1.5.6.jar:1.5.6]
at org.apache.commons.mail.Email.sendMimeMessage(Email.java:1459) ~[commons-email-1.5.jar:1.5]
... 4 more
Caused by: java.lang.RuntimeException: Unexpected error: java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty
at sun.security.validator.PKIXValidator.<init>(PKIXValidator.java:104) ~[?:1.8.0_272]
at sun.security.validator.Validator.getInstance(Validator.java:181) ~[?:1.8.0_272]
at sun.security.ssl.X509TrustManagerImpl.getValidator(X509TrustManagerImpl.java:302) ~[?:1.8.0_272]
at sun.security.ssl.X509TrustManagerImpl.checkTrustedInit(X509TrustManagerImpl.java:176) ~[?:1.8.0_272]
at sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:189) ~[?:1.8.0_272]
at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:129) ~[?:1.8.0_272]
at sun.security.ssl.CertificateMessage$T12CertificateConsumer.checkServerCerts(CertificateMessage.java:638) ~[?:1.8.0_272]
at sun.security.ssl.CertificateMessage$T12CertificateConsumer.onCertificate(CertificateMessage.java:473) ~[?:1.8.0_272]
at sun.security.ssl.CertificateMessage$T12CertificateConsumer.consume(CertificateMessage.java:369) ~[?:1.8.0_272]
at sun.security.ssl.SSLHandshake.consume(SSLHandshake.java:377) ~[?:1.8.0_272]
at sun.security.ssl.HandshakeContext.dispatch(HandshakeContext.java:444) ~[?:1.8.0_272]
at sun.security.ssl.HandshakeContext.dispatch(HandshakeContext.java:422) ~[?:1.8.0_272]
at sun.security.ssl.TransportContext.dispatch(TransportContext.java:182) ~[?:1.8.0_272]
at sun.security.ssl.SSLTransport.decode(SSLTransport.java:156) ~[?:1.8.0_272]
at sun.security.ssl.SSLSocketImpl.decode(SSLSocketImpl.java:1202) ~[?:1.8.0_272]
at sun.security.ssl.SSLSocketImpl.readHandshakeRecord(SSLSocketImpl.java:1111) ~[?:1.8.0_272]
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:398) ~[?:1.8.0_272]
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:370) ~[?:1.8.0_272]
at com.sun.mail.util.SocketFetcher.configureSSLSocket(SocketFetcher.java:598) ~[javax.mail-1.5.6.jar:1.5.6]
at com.sun.mail.util.SocketFetcher.startTLS(SocketFetcher.java:525) ~[javax.mail-1.5.6.jar:1.5.6]
at com.sun.mail.smtp.SMTPTransport.startTLS(SMTPTransport.java:2059) ~[javax.mail-1.5.6.jar:1.5.6]
at com.sun.mail.smtp.SMTPTransport.protocolConnect(SMTPTransport.java:724) ~[javax.mail-1.5.6.jar:1.5.6]
at javax.mail.Service.connect(Service.java:366) ~[javax.mail-1.5.6.jar:1.5.6]
at javax.mail.Service.connect(Service.java:246) ~[javax.mail-1.5.6.jar:1.5.6]
at javax.mail.Service.connect(Service.java:195) ~[javax.mail-1.5.6.jar:1.5.6]
at javax.mail.Transport.send0(Transport.java:254) ~[javax.mail-1.5.6.jar:1.5.6]
at javax.mail.Transport.send(Transport.java:124) ~[javax.mail-1.5.6.jar:1.5.6]
at org.apache.commons.mail.Email.sendMimeMessage(Email.java:1459) ~[commons-email-1.5.jar:1.5]
... 4 more
Caused by: java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty
at java.security.cert.PKIXParameters.setTrustAnchors(PKIXParameters.java:200) ~[?:1.8.0_272]
at java.security.cert.PKIXParameters.<init>(PKIXParameters.java:120) ~[?:1.8.0_272]
at java.security.cert.PKIXBuilderParameters.<init>(PKIXBuilderParameters.java:104) ~[?:1.8.0_272]
at sun.security.validator.PKIXValidator.<init>(PKIXValidator.java:102) ~[?:1.8.0_272]
at sun.security.validator.Validator.getInstance(Validator.java:181) ~[?:1.8.0_272]
at sun.security.ssl.X509TrustManagerImpl.getValidator(X509TrustManagerImpl.java:302) ~[?:1.8.0_272]
at sun.security.ssl.X509TrustManagerImpl.checkTrustedInit(X509TrustManagerImpl.java:176) ~[?:1.8.0_272]
at sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:189) ~[?:1.8.0_272]
at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:129) ~[?:1.8.0_272]
at sun.security.ssl.CertificateMessage$T12CertificateConsumer.checkServerCerts(CertificateMessage.java:638) ~[?:1.8.0_272]
at sun.security.ssl.CertificateMessage$T12CertificateConsumer.onCertificate(CertificateMessage.java:473) ~[?:1.8.0_272]
at sun.security.ssl.CertificateMessage$T12CertificateConsumer.consume(CertificateMessage.java:369) ~[?:1.8.0_272]
at sun.security.ssl.SSLHandshake.consume(SSLHandshake.java:377) ~[?:1.8.0_272]
at sun.security.ssl.HandshakeContext.dispatch(HandshakeContext.java:444) ~[?:1.8.0_272]
at sun.security.ssl.HandshakeContext.dispatch(HandshakeContext.java:422) ~[?:1.8.0_272]
at sun.security.ssl.TransportContext.dispatch(TransportContext.java:182) ~[?:1.8.0_272]
at sun.security.ssl.SSLTransport.decode(SSLTransport.java:156) ~[?:1.8.0_272]
at sun.security.ssl.SSLSocketImpl.decode(SSLSocketImpl.java:1202) ~[?:1.8.0_272]
at sun.security.ssl.SSLSocketImpl.readHandshakeRecord(SSLSocketImpl.java:1111) ~[?:1.8.0_272]
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:398) ~[?:1.8.0_272]
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:370) ~[?:1.8.0_272]
at com.sun.mail.util.SocketFetcher.configureSSLSocket(SocketFetcher.java:598) ~[javax.mail-1.5.6.jar:1.5.6]
at com.sun.mail.util.SocketFetcher.startTLS(SocketFetcher.java:525) ~[javax.mail-1.5.6.jar:1.5.6]
at com.sun.mail.smtp.SMTPTransport.startTLS(SMTPTransport.java:2059) ~[javax.mail-1.5.6.jar:1.5.6]
at com.sun.mail.smtp.SMTPTransport.protocolConnect(SMTPTransport.java:724) ~[javax.mail-1.5.6.jar:1.5.6]
at javax.mail.Service.connect(Service.java:366) ~[javax.mail-1.5.6.jar:1.5.6]
at javax.mail.Service.connect(Service.java:246) ~[javax.mail-1.5.6.jar:1.5.6]
at javax.mail.Service.connect(Service.java:195) ~[javax.mail-1.5.6.jar:1.5.6]
at javax.mail.Transport.send0(Transport.java:254) ~[javax.mail-1.5.6.jar:1.5.6]
at javax.mail.Transport.send(Transport.java:124) ~[javax.mail-1.5.6.jar:1.5.6]
at org.apache.commons.mail.Email.sendMimeMessage(Email.java:1459) ~[commons-email-1.5.jar:1.5]

--

--