无认证信任证书的JavaMail SSL

无认证信任证书的JavaMail SSL,java,smtp,jakarta-mail,Java,Smtp,Jakarta Mail,我有一个带有SSL(端口465)的本地邮件服务器(hMailServer)和一个自签名证书 域名是“foobar.com” 我已将我的属性设置为启用ssl、禁用身份验证和信任任何主机 props.put("mail.smtp.auth", "false"); props.put("mail.smtp.ssl.enable", "true"); props.put("mail.smtp.ssl.trust", "*"); 如果我通过静态调用将消息发送到Transport.

我有一个带有SSL(端口465)的本地邮件服务器(hMailServer)和一个自签名证书

域名是“foobar.com”

我已将我的
属性设置为启用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握手…

你要求一个“SMTP”传输。设置“smtp”传输的属性。由于您已将“mail.smtp.ssl.enable”属性设置为“true”,您只需请求“smtp”传输,它将使用ssl。

最好的解决方案是使用以下行

    MailSSLSocketFactory socketFactory = new MailSSLSocketFactory();
    socketFactory.setTrustAllHosts(true);

这是使用Spring framework的无身份验证信任证书的JavaMail SSL解决方案,请按如下所述更改.xml文件。您可以在快照中看到该解决方案

javax.net.ssl.SSLSocketFactory 真的


如果您希望邮件服务器必须在ssl中,请将其更改为false,也就是说,在代码段末尾的注释行中执行
Transport t=session.getTransport(“smtp”)
而不是
…“smtps”)