无法使用SMTP发送电子邮件(获取javax.mail.MessagingException:无法将套接字转换为TLS;)

我编写了以下代码,使用javamail API通过SMTP作为TLS发送电子邮件,因为不支持SSL,但我最终得到以下exception。 请参阅下面的代码。 我使用过调试模式,在代码下面你也可以找到exception。

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 = "---------@mydomain.com"; 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("---------@mydomain.com")); message.setRecipients(Message.RecipientType.TO, InternetAddress.parse("---------@mydomain.com")); 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跟踪

 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.(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.(DHCrypt.java:117) ... 18 more 

任何人都可以帮我调试这个吗? 提前致谢!

我通过评论下面的属性解决了这个问题

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

并且代码执行时没有错误或警告,或者只是从上面的源代码中删除这一行。 它的工作就像一个魅力直到约会。

注释掉属性“mail.smtp.starttls.enable”意味着你回退到默认和不安全的连接,只有当远程SMTP主机还接受端口587上的不安全传输时(邮件提交端口与端口25)用于最终交付或中继操作)。 在我的上下文中,TLS在587是强制性的,任何尝试打开没有TLS的会话都会产生SMTP服务器错误响应“530必须首先发出STARTTLS命令”。 然后单独将“mail.smtp.starttls.enable”设置为“true”仍会产生相同的错误“无法将套接字转换为TLS”,但现在有一个线索:“服务器不受信任”。 实际上,您必须在JVM启动属性中定义一个密钥库,该密钥库将包含以受信任的根证书结尾的证书链,或者使用此额外属性强制信任:“ mail.smtp.ssl.trust ”设置为远程主机名。

例如,在Spring支持javamail(您可以轻松映射到普通的javamail API)中配置整个内容需要以下所有内容:

        true theRemoteSmtpServer true    

确保您的防病毒软件没有阻止该应用程序。 就我而言,Avast阻止我在Java SE应用程序中发送电子邮件。

我有一个与smtp.gmail.com相同的问题,并通过以下步骤修复

  1. 根据berhauz评论改变了我的代码
  2. 通过以下链接更改了Gmail设置: https : //www.google.com/settings/security/lesssecureapps

看起来您的服务器使用的SSL实现与您正在使用的JDK版本中的SSL实现不兼容。 文件SSLNOTES.txt (也包含在JavaMail下载包中)有一些调试技巧。 您可能需要JDK SSL专家来对其进行排序。

如果您不想使用SSL,并且您使用的是smtp而不是smtps,请尝试这些设置

 mail.smtp.starttls.enable=false mail.transport.protocol=smtp 

我有这个问题。 原因是我们的管理员阻止了TLS和SSL协议。

堆栈跟踪显示问题的实际原因是:

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

您遇到了旧版本Java的限制,该版本不支持长度超过1024位的DH素数,这是您的SMTP服务器可能需要的。 以下是相关的错误条目:

Java 8中删除了此限制/限制(请参阅发行说明 )。

请注意,正如已经指出的那样,禁用STARTTLS的“修复”不是真正的修复:它意味着您的密码将以纯文本forms发送,此外,这仅适用于允许端口587上的未加密流量的SMTP服务器。

我通过禁用我的病毒防护来解决这个问题。