我有一个带有SSL(端口465)的本地邮件服务器(hMailServer)和一个自签名证书。
域名为“foobar.com”
我已设置Properties
以启用ssl,禁用身份验证并信任任何主机
props.put("mail.smtp.auth", "false");
props.put("mail.smtp.ssl.enable", "true");
props.put("mail.smtp.ssl.trust", "*");
如果我通过静态调用将消息发送到Transport.send()
电子邮件已发送。
如果我尝试从会话中获取transport
实例,那么我得到
javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
静态调用如何避免SSLHandshakeException?
这是我的测试代码:
public static void main(String[] args) throws Exception {
Properties props = new Properties();
props.put("mail.smtp.host", "127.0.0.1");
props.put("mail.debug", "false");
props.put("mail.smtp.port", "465");
props.put("mail.smtp.timeout", "60000");
props.put("mail.smtp.auth", "false");
props.put("mail.smtp.sendpartial", "true");
props.put("mail.smtp.ssl.enable", "true");
props.put("mail.smtp.ssl.trust", "*");
Session session = Session.getInstance(props);
Message message = new MimeMessage(session);
message.setFrom(new InternetAddress("mrFoo@foobar.com"));
message.setRecipients(Message.RecipientType.TO, InternetAddress.parse("you@foobar.com"));
message.setSubject("Just a Test " + new Date());
message.setText("Hello World");
//Comment and uncomment to test
Transport.send(message, message.getAllRecipients());
//Transport t = session.getTransport("smtps");
//t.connect();
//t.sendMessage(message, message.getAllRecipients());
//t.close();
}
这是一个隐藏在外部的本地系统,所以我不担心中间人攻击生成自己的证书来绕过SSL握手...
答案 0 :(得分:7)
你要求“smtps”运输。您设置“smtp”传输的属性。由于您已将“mail.smtp.ssl.enable”属性设置为“true”,因此您可以要求“smtp”传输,它将使用SSL。
答案 1 :(得分:0)
最佳解决方案是使用以下行
MailSSLSocketFactory socketFactory = new MailSSLSocketFactory();
socketFactory.setTrustAllHosts(true);
答案 2 :(得分:0)
这是使用Spring框架没有身份验证信任证书的JavaMail SSL解决方案,如下所述更改.xml文件。您可以在快照 See the image description here
中看到解决方案javax.net.ssl.SSLSocketFactory 真
如果您希望邮件服务器必须在ssl
中,请将其更改为 false