Javamail无法将套接字转换为TLS GMail

use*_*206 45 java email gmail jakarta-mail

我试图通过gmails SMTP Server使用JavaMail发送电子邮件.但是这段代码.

final String username = "mygmail@gmail.com";
    final String password = "mygmailpassword";

    Properties props = new Properties();
    props.put("mail.smtp.auth", true);
    props.put("mail.smtp.starttls.enable", true);
    props.put("mail.smtp.host", "smtp.gmail.com");
    props.put("mail.smtp.port", "587");

    Session session = Session.getInstance(props,
            new javax.mail.Authenticator() {
                protected PasswordAuthentication getPasswordAuthentication() {
                    return new PasswordAuthentication(username, password);
                }
            });

    try {

        Message message = new MimeMessage(session);
        message.setFrom(new InternetAddress("no-reply@gmail.com"));
        message.setRecipients(Message.RecipientType.TO,
                InternetAddress.parse("test@gmail.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);
    }
Run Code Online (Sandbox Code Playgroud)

返回此错误

Could not convert socket to TLS;
Run Code Online (Sandbox Code Playgroud)

完整的Stacktrace

Exception in thread "main" java.lang.RuntimeException: javax.mail.MessagingException: Could not convert socket to TLS;
  nested exception is:
    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
    at Test.main(Test.java:43)
Caused by: javax.mail.MessagingException: Could not convert socket to TLS;
  nested exception is:
    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
    at com.sun.mail.smtp.SMTPTransport.startTLS(SMTPTransport.java:1907)
    at com.sun.mail.smtp.SMTPTransport.protocolConnect(SMTPTransport.java:666)
    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 Test.main(Test.java:38)
Caused by: 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
    at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:174)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1649)
    at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Handshaker.java:241)
    at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Handshaker.java:235)
    at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1206)
    at com.sun.net.ssl.internal.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:136)
    at com.sun.net.ssl.internal.ssl.Handshaker.processLoop(Handshaker.java:593)
    at com.sun.net.ssl.internal.ssl.Handshaker.process_record(Handshaker.java:529)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:893)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1138)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1165)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1149)
    at com.sun.mail.util.SocketFetcher.configureSSLSocket(SocketFetcher.java:549)
    at com.sun.mail.util.SocketFetcher.startTLS(SocketFetcher.java:486)
    at com.sun.mail.smtp.SMTPTransport.startTLS(SMTPTransport.java:1902)
    ... 7 more
Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
    at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:323)
    at sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:217)
    at sun.security.validator.Validator.validate(Validator.java:218)
    at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:126)
    at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:209)
    at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:249)
    at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1185)
    ... 17 more
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
    at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:174)
    at java.security.cert.CertPathBuilder.build(CertPathBuilder.java:238)
    at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:318)
    ... 23 more
Run Code Online (Sandbox Code Playgroud)

小智 119

props.put("mail.smtp.ssl.trust", "smtp.gmail.com");
Run Code Online (Sandbox Code Playgroud)

  • 您是否可以扩展为什么/如何认为此提议的解决方案将解决问题? (10认同)
  • 从javamail docs - `mail.smtp.ssl.trust`如果设置,并且尚未指定套接字工厂,则启用MailSSLSocketFactory.如果设置为"*",则所有主机都是可信的.如果设置为以空格分隔的主机列表,则这些主机是受信任的.否则,信任取决于服务器提供的证书. (8认同)
  • 对我来说 `props.put("mail.smtp.ssl.trust", "*");` 成功了 (3认同)
  • 这个做了魔术,但答案可以更好地扩展一些像@Denomales说的更多细节.好的提示虽然.我的猜测是,这个道具告诉你程序盲目信任ssl连接是否有正确的证书? (2认同)

小智 24

我禁用avast防病毒10分钟,让它工作.


shi*_*raj 23

确保您的防病毒程序没有干扰,并确保在防火墙中添加排除项.

  • 真的说.Avast正在制造问题.Thanx哥们 (4认同)
  • 我是这个问题的受害者,我给的是我自己的解决方案, (3认同)
  • 同样在这里,Avast 不知何故是问题所在 (3认同)

Del*_*nte 16

当用于发送电子邮件的默认 SSL 协议设置为 TLSv1 并且 smtp 服务器不再支持此协议时,我遇到了类似的问题。技巧是使用较新的协议:

mail.smtp.ssl.protocols=TLSv1.2


Vla*_*adi 9

检查您是否拥有所有这些字段

Properties props = new Properties();
    props.put("mail.smtp.host", "smtp.gmail.com");
    props.put("mail.smtp.port", "587");
    props.put("mail.smtp.auth", "true");
    props.put("mail.smtp.ssl.protocols", "TLSv1.2");
    props.put("mail.smtp.starttls.enable", "true");
Run Code Online (Sandbox Code Playgroud)


ℛɑƒ*_*ƒæĿ 8

@carlos的第一个答案为我工作:

session.getProperties().put("mail.smtp.ssl.trust", "smtp.gmail.com");
Run Code Online (Sandbox Code Playgroud)

我已经测试了下面的属性并且对我来说也很完美:

session.getProperties().put("mail.smtp.starttls.enable", "true");
Run Code Online (Sandbox Code Playgroud)

这两个属性单独解决了这类问题,但保证我同时使用了这两个问题.


Pet*_*ski 7

经过一整天的搜索,我禁用了 Avast 10 分钟和 Windows 防火墙(重要),一切都开始工作了!

这是我的错误:

Mail server connection failed; nested exception is javax.mail.MessagingException: Could not convert socket to TLS; nested exception is: 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. Failed messages: javax.mail.MessagingException: Could not convert socket to TLS; nested exception is: 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  
Run Code Online (Sandbox Code Playgroud)

以下是通过向 SMTP 端口 587(或您的应用程序使用的任何端口)添加排除项来解决 Avast 19.8.2393 中的问题的方法

  1. 打开 Avast

  2. 点击“设置”

  3. 单击“疑难解答”,然后单击“打开旧设置”

在此处输入图片说明

  1. 再次单击“疑难解答”,向下滚动到“重定向设置”并删除您的应用程序使用的端口。

在此处输入图片说明

就我而言,我刚刚从 SMTP 端口中删除了 587。

现在我可以使用 Avast 并打开我的 Windows 防火墙(无需为防火墙添加额外的排除项)。

这是我的application.properties电子邮件属性:

###### I am using a Google App Password which I generated in my Gmail Security settings ######
spring.mail.host = smtp.gmail.com
spring.mail.port = 587
spring.mail.protocol = smtp
spring.mail.username = gmail account
spring.mail.password = password
spring.mail.properties.mail.smtp.auth=true
spring.mail.properties.mail.smtp.starttls.enable=true
spring.mail.properties.mail.smtp.connectiontimeout=5000
spring.mail.properties.mail.smtp.timeout=5000
spring.mail.properties.mail.smtp.writetimeout=5000
Run Code Online (Sandbox Code Playgroud)


Pri*_*agh 7

上面的 application.properties 对我来说效果惊人:

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
Run Code Online (Sandbox Code Playgroud)


nur*_*urb 6

在我的情况下,问题是通过删除该行来解决的

prop.put("mail.smtp.starttls.enable", "true");
Run Code Online (Sandbox Code Playgroud)

可能是因为电子邮件服务器上的一些 ssl 配置错误,我不确定。电子邮件服务器管理员从不承认这一点,并且总是责怪托管服务提供商 :)


isa*_*pir 5

这取决于“嵌套异常”。如果嵌套异常是“没有适当的协议”,则在系统属性中指定协议:

-Dmail.smtp.ssl.protocols=TLSv1.2
Run Code Online (Sandbox Code Playgroud)

我看到有些人建议在创建 STMP 会话的代码中设置它,但如果您想将来更新该值,则需要修补和部署。使用系统属性允许您在不更改代码的情况下更新它。


Bil*_*non -1

尝试使用 JavaMail 附带的 smtpsend 程序,如此处所述。如果同样失败,则说明您的 JDK 配置或网络配置有问题。