Unable to send an email using SMTP (Getting javax.mail.MessagingException: Could not convert socket to TLS;)
Asked Answered
N

14

19

I have written the following code for sending email using javamail API through SMTP as TLS as SSL is not supported but I ended up with the following exception. Please see my code below. I have used debugging mode and below the code you can find the exception as well.

import java.util.Properties;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;

public class SendMailTLS {

    public static void main(String[] args) {

        final String username = "[email protected]";
        final String password = "***********";

        Properties props = new Properties();
        props.put("mail.smtp.auth", "true");
        props.put("mail.smtp.starttls.enable", "true");
        props.put("mail.smtp.host", "mail.mydomain.com");
        props.put("mail.smtp.debug", "true");
        props.put("mail.smtp.port", "587");

        Session session = Session.getInstance(props,
          new javax.mail.Authenticator() {
            protected PasswordAuthentication getPasswordAuthentication() {
                return new PasswordAuthentication(username, password);
            }
          });
        session.setDebug(true);

        try {

            Message message = new MimeMessage(session);
            message.setFrom(new 
                  InternetAddress("[email protected]"));
            message.setRecipients(Message.RecipientType.TO,
            InternetAddress.parse("[email protected]"));
            message.setSubject("Testing Subject");
            message.setText("Dear Mail Crawler,"
                + "\n\n No spam to my email, please!");

            Transport.send(message);

            System.out.println("Done");

        } catch (MessagingException e) {
            throw new RuntimeException(e);
        }
    }
}

Exception trace

DEBUG: setDebug: JavaMail version 1.4.5
DEBUG: getProvider() returning javax.mail.Provider[TRANSPORT,smtp,com.sun.mail.smtp.SMTPTransport,Sun Microsystems, Inc]
DEBUG SMTP: useEhlo true, useAuth true
DEBUG SMTP: useEhlo true, useAuth true
DEBUG SMTP: trying to connect to host "mail.mydomain.com", port 587, isSSL false
220-cpanel35.per.syra.net.au ESMTP Exim 4.80 #2 Fri, 05 Oct 2012 17:28:56 +0800 
220-We do not authorize the use of this system to transport unsolicited, 
220 and/or bulk e-mail.
DEBUG SMTP: connected to host "mail.mydomain.com", port: 587

EHLO xxxxxx.xxxxx.com
250-cpanel35.per.syra.net.au Hello xxxx.xxxxx.com [xx.xx.xx.xxx]i
250-SIZE 52428800
250-8BITMIME
250-PIPELINING
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 ""
STARTTLS
220 TLS go ahead
Exception in thread "main" java.lang.RuntimeException: javax.mail.MessagingException: Could not convert socket to TLS;
  nested exception is:
    javax.net.ssl.SSLException: java.lang.RuntimeException: Could not generate DH keypair
    at SendMailTLS.main(SendMailTLS.java:52)
Caused by: javax.mail.MessagingException: Could not convert socket to TLS;
  nested exception is:
    javax.net.ssl.SSLException: java.lang.RuntimeException: Could not generate DH keypair
    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)
    at javax.mail.Service.connect(Service.java:176)
    at javax.mail.Service.connect(Service.java:125)
    at javax.mail.Transport.send0(Transport.java:194)
    at javax.mail.Transport.send(Transport.java:124)
    at SendMailTLS.main(SendMailTLS.java:47)
Caused by: javax.net.ssl.SSLException: java.lang.RuntimeException: Could not generate DH keypair
    at sun.security.ssl.Alerts.getSSLException(Alerts.java:208)
    at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1868)
    at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1826)
    at sun.security.ssl.SSLSocketImpl.handleException(SSLSocketImpl.java:1809)
    at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1328)
    at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1305)
    at com.sun.mail.util.SocketFetcher.configureSSLSocket(SocketFetcher.java:548)
    at com.sun.mail.util.SocketFetcher.startTLS(SocketFetcher.java:485)
    at com.sun.mail.smtp.SMTPTransport.startTLS(SMTPTransport.java:1913)
    ... 7 more
Caused by: java.lang.RuntimeException: Could not generate DH keypair
    at sun.security.ssl.DHCrypt.<init>(DHCrypt.java:123)
    at sun.security.ssl.ClientHandshaker.serverKeyExchange(ClientHandshaker.java:618)
    at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:202)
    at sun.security.ssl.Handshaker.processLoop(Handshaker.java:868)
    at sun.security.ssl.Handshaker.process_record(Handshaker.java:804)
    at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:998)
    at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1294)
    at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1321)
    ... 11 more
Caused by: java.security.InvalidAlgorithmParameterException: Prime size must be multiple of 64, and can only range from 512 to 1024 (inclusive)
    at com.sun.crypto.provider.DHKeyPairGenerator.initialize(DHKeyPairGenerator.java:120)
    at java.security.KeyPairGenerator$Delegate.initialize(KeyPairGenerator.java:658)
    at sun.security.ssl.DHCrypt.<init>(DHCrypt.java:117)
    ... 18 more

Can anyone help me debug this? Thanks in advance!

Nibbs answered 5/10, 2012 at 9:57 Comment(0)
N
17

I resolved this issue by just commenting out the below property

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

and the code got executed with no errors or warning or simply delete this line from the above source code. It is working like a charm till date.

Nibbs answered 12/4, 2013 at 9:27 Comment(5)
In other words set this property as mail.smtp.starttls.enable=falseNibbs
In other words, your password is traveling through the internets as plain text. Very bad advice.Selfsacrifice
Yeah, this is not encrypted. It will also likely send your emails as junk mail.Eudoxia
@MartinErlic how can u send your password encrypted?Ta
You have failed the whole propose of using TLS! Now it is an unsecured message.Deth
S
19

Commenting-out the property mail.smtp.starttls.enable means you fall back to a default and unsecured connection, which would work only if the remote SMTP host also accepts unsecured transport on port 587 (the port for mail submission versus port 25 for end-delivery or relay operations).

In my context, TLS is compulsory on 587 and any attempt to open a session without TLS yield the SMTP server error response 530 Must issue a STARTTLS command first.

Then setting mail.smtp.starttls.enable to true alone still yield the same error Could not convert socket to TLS but now with a clue: Server is not trusted. Indeed, you must have either a keystore defined in the JVM start properties that would contain a certificate chain ending onto a trusted root certificate, either enforce trust with this extra property: mail.smtp.ssl.trust set to the remote host name.

Configuring the whole stuff in Spring support for javamail for instance (which you can easily map to plain javamail API) requires all of the following:

<bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
<property name="host" value="theRemoteSmtpServer" />
<property name="port" value="587" />
<property name="username" value="muUserID" />
<property name="password" value="myPassword" />
<property name="javaMailProperties">
    <props>
        <prop key="mail.smtp.starttls.enable">true</prop>
        <prop key="mail.smtp.ssl.trust">theRemoteSmtpServer</prop>
        <prop key="mail.smtp.auth">true</prop>
    </props>
</property>
</bean>
Sparkle answered 15/1, 2015 at 21:55 Comment(3)
This worked for me... Thank you so much. I was trying to overcome this issue for last 24 hrs. Finally your post came to my rescue!! :)Lemus
This worked for me. I was missing the 'mail.smtp.ssl.trust' property and adding it fixed it for me. Thanks!Marvel
I was having the same problem under Glassfish 5.0.1 (not released yet). The mail.smtp.ssl.trust property fixed it for me.Williamsen
N
17

I resolved this issue by just commenting out the below property

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

and the code got executed with no errors or warning or simply delete this line from the above source code. It is working like a charm till date.

Nibbs answered 12/4, 2013 at 9:27 Comment(5)
In other words set this property as mail.smtp.starttls.enable=falseNibbs
In other words, your password is traveling through the internets as plain text. Very bad advice.Selfsacrifice
Yeah, this is not encrypted. It will also likely send your emails as junk mail.Eudoxia
@MartinErlic how can u send your password encrypted?Ta
You have failed the whole propose of using TLS! Now it is an unsecured message.Deth
F
4

Make sure your antivirus software is not blocking the application. In my case Avast was blocking me from sending e-mails in a Java SE application.

Fibrilla answered 10/11, 2014 at 18:47 Comment(2)
please post english answersVow
Andre Andrade solved it for me! In my case, this was the most useful answer (and, since it takes 1 minute to test this issue, everyone should try it before wasting hours on other things)Fleenor
P
4

I had a same issue with smtp.gmail.com and fixed with the following steps

  1. changed my code as per berhauz comments
  2. changed in Gmail settings from this link: https://www.google.com/settings/security/lesssecureapps
Phosgenite answered 19/1, 2015 at 19:8 Comment(0)
Q
4

Maybe this issue related to security and smtp.ssl is not trusted that's why issue occurs.

I resolve this issue just add a property

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

Now it is working fine for me.

Quarterstaff answered 10/10, 2019 at 6:38 Comment(0)
R
3

If you don't want to use SSL, and you're using smtp instead of smtps try these settings

mail.smtp.starttls.enable=false
mail.transport.protocol=smtp
Rickeyricki answered 22/8, 2013 at 20:6 Comment(0)
E
2

It looks like the SSL implementation used by your server is not compatible with the SSL implementation in the version of the JDK you're using. The file SSLNOTES.txt (also included in the JavaMail download bundle) has some debugging tips. You might need a JDK SSL expert to sort this out.

Egotism answered 5/10, 2012 at 19:22 Comment(0)
P
2

I had this problem. the reason was our administrator had blocked TLS and SSL protocols.

Polymerous answered 26/8, 2013 at 9:16 Comment(0)
H
2
session.getProperties().put("mail.smtp.starttls.enable","true");
props.put("mail.smtp.ssl.trust", "smtp.office365.com(site where your account is)");
props.put("mail.smtp.starttls.enable", true);

These codes should be able to start a ttls communication and get the mail service running.

In addition to this the antivirus creates a firewall that stops the handshake from happening.

Historic answered 10/5, 2019 at 3:44 Comment(1)
Specifically in the case of using smtp.office365.com this three lines helped me to get an OK response from the server after several hours of trying. Thank you! Response: 250 2.0.0 OK <BYAPR01MB460038D6F7F9503DCF190BDCF0650@BYAPR01MB4600.prod.exchangelabs.com>Scimitar
S
1

After fighting all day this works for me (using spring boot , MailSender , aws)

spring.mail.host=smtp.gmail.com
[email protected]
spring.mail.password=--------------
spring.mail.properties.mail.transport.protocol=smtp
spring.mail.properties.mail.smtp.port=465
spring.mail.properties.mail.smtp.auth=true
spring.mail.properties.mail.smtp.starttls.enable=true
spring.mail.properties.mail.smtp.ssl.enable=true
spring.mail.properties.mail.smtp.starttls.required=true
spring.mail.properties.mail.smtp.ssl.trust=smtp.gmail.com
Science answered 7/2, 2021 at 20:15 Comment(0)
T
1

I spent hours on this error, until I found out that tomcat used TLS version 1.1 while the smtp server supports only TLS 1.2 and 1.3.

props.put("mail.smtp.ssl.protocols", "TLSv1.2");  

Setting TLS version to 1.2 solved my problem

Tellurize answered 27/4, 2021 at 18:13 Comment(3)
This solved my issue with communicating with GMail.Villatoro
which tomcat versionJandel
8.0.30 was the tomcat versionTellurize
T
0

The stack trace reveals that the actual cause of the problem is this:

java.security.InvalidAlgorithmParameterException: Prime size must be multiple of 64, and can only range from 512 to 1024 (inclusive)

You are running into a limitation of older versions of Java that did not support DH primes longer than 1024 bits, which your SMTP server was probably requiring. Here are the relevant bug entries:

This restriction/limitation was removed in Java 8 (see the release notes).

Note that as has been pointed out already, your "fix" of disabling STARTTLS is not a real fix: It means your password will be sent as plain text, plus this will only work for SMTP servers that allow unencrypted traffic on port 587.

Thales answered 2/6, 2016 at 11:35 Comment(0)
C
0

I resolved this issue by disabling my virus guard.

Carlyle answered 3/8, 2018 at 11:16 Comment(0)
A
0

Q) Could not convert socket to TLS & Server is not trusted issue?

Ans: I also faced same issue, just add below code in application.properties file then it will resolve.

  1. Below code for application.yml file.
    spring:  
      mail:  
        host: smtp.gmail.com  
        port: 587
        username: [email protected]
        password: yourpassword
        protocol: smtp
    properties:
      mail:
        smtp:
          starttls:
            enable: true
            required: true
          auth: true
          ssl:
            trust: smtp.gmail.com
  1. Below code for application.properties file.
spring.mail.host=smtp.gmail.com
spring.mail.port=587
[email protected]
spring.mail.password=yourpassword
spring.mail.protocol=smtp

spring.mail.properties.mail.smtp.starttls.enable=true
spring.mail.properties.mail.smtp.starttls.required=true
spring.mail.properties.mail.smtp.auth=true
spring.mail.properties.mail.smtp.ssl.trust=smtp.gmail.com
Armful answered 12/1, 2023 at 16:9 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.