Reputation: 1436
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
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.
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
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
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
Reputation: 139
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
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
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
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
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
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
Reputation: 960
I had a same issue with smtp.gmail.com and fixed with the following steps
Upvotes: 4
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
Reputation: 7592
I had this problem. the reason was our administrator had blocked TLS and SSL protocols.
Upvotes: 2
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
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