我已经编写了以下代码,用于通过SMTP作为TLS使用javamail API发送电子邮件,因为不支持SSL但我最终遇到以下异常。请参阅下面的代码。我使用了调试模式,在代码下面你也可以找到异常。
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);
}
}
}
异常追踪
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
任何人都可以帮我调试吗?提前谢谢!
答案 0 :(得分:12)
我通过评论以下属性来解决这个问题
props.put("mail.smtp.starttls.enable", "true");
并且代码执行时没有错误或警告,或者只是从上面的源代码中删除此行。到目前为止它一直像魅力一样。
答案 1 :(得分:11)
注释掉属性mail.smtp.starttls.enable
意味着您回退到默认且不安全的连接,仅当远程SMTP主机还接受端口587
上的不安全传输时才会起作用(邮件提交端口)与端口25进行终端交付或中继操作)。
在我的上下文中,587
必须使用TLS,并且任何尝试打开没有TLS的会话都会产生SMTP服务器错误响应 530必须首先发出STARTTLS命令。
然后单独将mail.smtp.starttls.enable
设置为true
仍然会产生相同的错误无法将套接字转换为TLS 但现在有了线索:服务器不受信任。实际上,您必须在JVM启动属性中定义一个密钥库,该密钥库将包含以受信任的根证书结尾的证书链,或者使用此额外属性强制信任: mail.smtp.ssl.trust set到远程主机名。
配置Spring中对javamail的支持(例如,您可以轻松映射到普通的javamail API)需要以下所有内容:
<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>
答案 2 :(得分:4)
确保您的防病毒软件没有阻止该应用程序。就我而言,Avast阻止我在Java SE应用程序中发送电子邮件。
答案 3 :(得分:3)
我在使用smtp.gmail.com时遇到了同样的问题,并通过以下步骤进行了修复
答案 4 :(得分:2)
您的服务器使用的SSL实现看起来与您正在使用的JDK版本中的SSL实现不兼容。文件SSLNOTES.txt(也包含在JavaMail下载包中)有一些调试技巧。您可能需要JDK SSL专家对此进行排序。
答案 5 :(得分:2)
如果您不想使用SSL,并且您使用的是smtp而不是smtps,请尝试这些设置
mail.smtp.starttls.enable=false
mail.transport.protocol=smtp
答案 6 :(得分:1)
我有这个问题。原因是我们的管理员阻止了TLS和SSL协议。
答案 7 :(得分:1)
我通过禁用病毒防护解决了此问题。
答案 8 :(得分:1)
此问题可能与安全性有关,并且 smtp.ssl不可信,这就是发生此问题的原因。
我解决了这个问题,只需添加一个属性
spring.mail.properties.mail.smtp.ssl.trust=smtp.gmail.com
现在对我来说很好。
答案 9 :(得分:0)
堆栈跟踪显示问题的实际原因是:
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中删除了此限制/限制(请参阅the release notes)。
请注意,正如已经指出的,禁用STARTTLS的“修复”不是真正的修复:它意味着您的密码将以纯文本形式发送,此外,这仅适用于允许端口上未加密流量的SMTP服务器587。
答案 10 :(得分:0)
df[['Start_Time','End_Time']]=df[['Start_Time','End_Time']].apply(pd.to_datetime,1)
df.groupby('Name').apply(lambda x : (x['Start_Time']-x['End_Time'].shift()).dt.total_seconds().mean()/60)
Out[469]:
Name
A 10.0
B 5.0
dtype: float64
这些代码应该能够启动ttls通信并运行邮件服务。
此外,防病毒软件还会创建防火墙,以阻止握手发生。
答案 11 :(得分:0)
经过一整天的战斗,这对我有用(使用 spring boot、MailSender、aws)
spring.mail.host=smtp.gmail.com
spring.mail.username=-----------@gmail.com
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
答案 12 :(得分:0)
我在这个错误上花了几个小时,直到我发现 tomcat 使用 TLS 1.1 版,而 smtp 服务器仅支持 TLS 1.2 和 1.3。
props.put("mail.smtp.ssl.protocols", "TLSv1.2");
将 TLS 版本设置为 1.2 解决了我的问题