Nagarajan S R
Nagarajan S R

Reputation: 1436

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

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!

Upvotes: 19

Views: 112433

Answers (14)

MacTech. com
MacTech. com

Reputation: 1

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

Upvotes: 0

dimitris tseggenes
dimitris tseggenes

Reputation: 3186

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

Upvotes: 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

Upvotes: 1

Nagarajan S R
Nagarajan S R

Reputation: 1436

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.

Upvotes: 16

Abhishek
Abhishek

Reputation: 37

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.

Upvotes: 4

Binay Dhawa
Binay Dhawa

Reputation: 71

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.

Upvotes: 2

Bernard Hauzeur
Bernard Hauzeur

Reputation: 2403

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>

Upvotes: 21

sandali chethana
sandali chethana

Reputation: 19

I resolved this issue by disabling my virus guard.

Upvotes: 0

Grodriguez
Grodriguez

Reputation: 21995

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.

Upvotes: 0

Sudarsana Kasireddy
Sudarsana Kasireddy

Reputation: 960

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

Upvotes: 4

Andr&#233; Andrade
Andr&#233; Andrade

Reputation: 41

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.

Upvotes: 4

Ehsan Mirsaeedi
Ehsan Mirsaeedi

Reputation: 7592

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

Upvotes: 2

Erich
Erich

Reputation: 2773

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

Upvotes: 3

Bill Shannon
Bill Shannon

Reputation: 29971

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.

Upvotes: 2

Related Questions