无法将套接字转换为 TLS GMail

我试图通过 Gmail SMTP 服务器使用 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);
}

返回一个 this 错误:

无法将套接字转换为 TLS;

完整的堆栈跟踪:

线程“ main”java.lang 中的异常。 RuntimeException: javax.mail。 MessagingException: 无法将套接字转换为 TLS; 嵌套的例外是: 异常: sun.security.validator。验证器异常: PKIX 路径构建失败: sun.security.Provider.certpath。 SunCertPathBuilderException: 无法找到到所请求目标的有效认证路径 At Test.main (Test.java: 43) 引起原因: javax.mail.MessagingException: 无法将套接字转换为 TLS; 嵌套的例外是: 异常: sun.security.validator。验证器异常: PKIX 路径构建失败: sun.security.Provider.certpath。 SunCertPathBuilderException: 无法找到到所请求目标的有效认证路径 Http://com.sun.mail.smtp.SMTPTransport. startTLS (SMTPTransport. java: 1907) 您可以访问 com.sun.mail.smtp.SMTPTransportation. ProtocolConnect (SMTPTransport. java: 666) 在 javax.mail. Service.connect (Service.java: 317) 在 javax.mail. Service.connect (Service.java: 176) 在 javax.mail. Service.connect (Service.java: 125) Http://javax.mail. Transport. send0(Transport. java: 194) 在 javax.mail. Transport. send (Transportation t.java: 124) At Test.main (Test.java: 38) 由 javax.net.ssl.SSLHandshakeException: sun.security.validator 引起。 ValidatorException: PKIX 路径构建失败: sun.security.prover.certpath。 SunCertPathBuilderException: 无法找到到所请求目标的有效证书路径 在 com.sun.net.ssl.interal.ssl. Alerts.getSSLException (Alerts.java: 174) 在 com.sun.net.ssl.interal.ssl.SSLSocketImp.death (SSLSocketImp.java: 1649) 地址: com.sun.net.ssl.interal.ssl. Handshaker.fatalSE (Handshaker.java: 241) 地址: com.sun.net.ssl.interal.ssl. Handshaker.fatalSE (Handshaker.java: 235) 地址: com.sun.net.ssl.interal.ssl. ClientHandshaker.serverSecurities (ClientHandshaker.java: 1206) 在 com.sun.net.ssl.interal.ssl. ClientHandshaker.processMessage (ClientHandshaker.java: 136) 在 com.sun.net.ssl.interal.ssl. Handshaker.processLoop (Handshaker.java: 593) 地址: com.sun.net.ssl.interal.ssl. Handshaker.process _ record (Handshaker.java: 529) 请访问 com.sun.net.ssl.interal.ssl.SSLSocketImp.readRecord (SSLSocketImp.java: 893) 请访问 com.sun.net.ssl.interal.ssl.SSLSocketImp.PerformInitialHandshake (SSLSocketImp.java: 1138) 地址: com.sun.net.ssl.interal.ssl.SSLSocketImp.startHandshake (SSLSocketImp.java: 1165) 地址: com.sun.net.ssl.interal.ssl.SSLSocketImp.startHandshake (SSLSocketImp.java: 1149) 在 com.sun.mail.util. SocketFetcher.configureSSLSocket (SocketFetcher.java: 549) 在 com.sun.mail.util. SocketFetcher.startTLS (SocketFetcher.java: 486) Http://com.sun.mail.smtp.SMTPTransportation. startTLS (SMTPTransport. java: 1902) 还有七个 由: sun.security.validator 引起。 ValidatorException: PKIX 路径构建失败: sun.security.prover.certpath。 SunCertPathBuilderException: 无法找到到所请求目标的有效证书路径 请访问 sun.security.validator.PKIXValidator.doBuild (PKIXValidator.java: 323) Http://sun.security.validator.PKIXValidator.engineering 验证(PKIXValidator.java: 217) 在 sun.security.validator. Validator.valid(Validator.java: 218) 在 com.sun.net.ssl.interal.ssl.X509TrustManagerImp.valid(X509TrustManagerImp.java: 126) X509TrustManagerImp.checkServerTrusted (X509TrustManagerImp.java: 209) X509TrustManagerImp.checkServerTrusted (X509TrustManagerImp.java: 249) 地址: com.sun.net.ssl.interal.ssl. ClientHandshaker.serverSecurities (ClientHandshaker.java: 1185) 还有17个 原因是: sun.security.provision. certpath. SunCertPathBuilderException: 无法找到到所请求目标的有效证书路径 Http://sun.security.provision. certpath. SunCertPathBuilder.engineering Build (SunCertPathBuilder.java: 174) Cert. CertPathBuilder.build (CertPathBuilder.java: 238) 请访问 sun.security.validator.PKIXValidator.doBuild (PKIXValidator.java: 318) 还有23个

232649 次浏览

尝试使用 JavaMail 附带的 smtpsend 程序,如 给你所述。如果以同样的方式失败,那么您的 JDK 配置或网络配置就有问题。

props.put("mail.smtp.ssl.trust", "smtp.gmail.com");

请确保您的防病毒程序没有干扰,并确保添加一个排除到您的防火墙。

我关闭了 avast 杀毒软件10分钟,然后它就能工作了。

如果您的上下文是 android 应用程序, 然后确保你的安卓设备时间设置为当前日期和时间。 潜在的例外是 “ SSL 证书没有得到认证。”

这是可行的解决方案,兄弟,我保证

1)首先打开你想发送邮件的 gmail 帐户,比如你的“ xyz@gmail.com”

2)在 https://support.google.com/accounts/answer/6010255?hl=en下方开启此连结

3)点击“转到我账户中的“不太安全的应用程序”部分。”选项

4)然后打开它

就是这样:

这是我的密码

import javax.mail.*;
import javax.mail.internet.*;
import java.util.*;


public class SendEmail {


final String senderEmailID = "Sender Email id";
final String senderPassword = "Sender Pass word";
final String emailSMTPserver = "smtp.gmail.com";
final String emailServerPort = "465";
String receiverEmailID = null;
static String emailSubject = "Test Mail";
static String emailBody = ":)";
public SendEmail(String receiverEmailID, String emailSubject, String emailBody)
{
this.receiverEmailID=receiverEmailID;
this.emailSubject=emailSubject;
this.emailBody=emailBody;
Properties props = new Properties();
props.put("mail.smtp.user",senderEmailID);
props.put("mail.smtp.host", emailSMTPserver);
props.put("mail.smtp.port", emailServerPort);
props.put("mail.smtp.starttls.enable", "true");
props.put("mail.smtp.auth", "true");
props.put("mail.smtp.socketFactory.port", emailServerPort);
props.put("mail.smtp.socketFactory.class","javax.net.ssl.SSLSocketFactory");
props.put("mail.smtp.socketFactory.fallback", "false");
SecurityManager security = System.getSecurityManager();
try
{
Authenticator auth = new SMTPAuthenticator();
Session session = Session.getInstance(props, auth);
MimeMessage msg = new MimeMessage(session);
msg.setText(emailBody);
msg.setSubject(emailSubject);
msg.setFrom(new InternetAddress(senderEmailID));
msg.addRecipient(Message.RecipientType.TO,
new InternetAddress(receiverEmailID));
Transport.send(msg);
System.out.println("Message send Successfully:)");
}
catch (Exception mex)
{
mex.printStackTrace();
}
}
public class SMTPAuthenticator extends javax.mail.Authenticator
{
public PasswordAuthentication getPasswordAuthentication()
{
return new PasswordAuthentication(senderEmailID, senderPassword);
}
}
public static void main(String[] args) {
SendEmail mailSender;
mailSender = new SendEmail("Receiver Email id","Testing Code 2 example","Testing Code Body yess");
}


}

帮助我解决这个问题的是,在此之前我已经尝试了所有方法,将我安装的 JRE 配置为 JRE 1.8。

Eclipse 中的步骤: Windows > 首选项 > java > 安装的 JRE > jre1.8.0

如果设置为 jdk,切换到 jre (这是最新 Java 版本默认设置的)。

@ Carlos的第一个回答对我很有用:

session.getProperties().put("mail.smtp.ssl.trust", "smtp.gmail.com");

我已经测试了下面的特性,对我来说也很完美:

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

这两个属性本身就解决了这种类型的问题,但是我保证两者都使用了。

试试把端口改成465

mail.smtp.socketFactory.port=465
mail.smtp.port=465

在我的情况下,这个问题是由 删除线解决的

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

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

如果应用程序不支持 SMTP 主机正在使用的 TLS 版本,也可以这样做。

例如,当您的应用程序(或使用旧的 javax.mail JAR 的 Java 程序)只支持 TLSv1.1时,尝试配置一个使用 TLSv1.2的 SMTP 服务器而不使用备份。

经过一整天的搜索,我禁用了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

下面是如何通过在 SMTP 端口587(或应用程序使用的任何端口)中添加一个排除项来修复 Agreat 19.8.2393 中的问题:

  1. 打开,停下

  2. 点击“设置”

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

enter image description here

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

enter image description here

在我的例子中,我只是从 SMTP 端口删除了587。

现在我可以使用 Agreat 并且打开我的 Windows 防火墙(不需要为防火墙添加额外的排除)。

以下是我的 应用性能电子邮件属性:

###### 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

以上应用。属性为我工作惊人:

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

检查 JavaMail 库的版本(mail.jar 或 javax.mail.jar)。 从这里下载最新版本: < a href = “ https://javaee.github.io/javamail/”rel = “ nofollow norefrer”> https://javaee.github.io/javamail/

是的,它在本地主机上对我有效:

props.put("mail.smtp.ssl.trust", "smtp.gmail.com");

该错误仅在 localhost 上引发,因此您也应该在远程服务器上尝试。通常,上面提到的代码片段在没有 ssl.trust属性的情况下工作得很好

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

Ssl.protocol = TLSv1.2

下面 application.properties中的一组属性为我解决了这个问题:

spring.mail.host=smtp.gmail.com
spring.mail.port=587
spring.mail.username=<gmail_id>
spring.mail.password=<gmail_password>
spring.mail.properties.mail.smtp.ssl.trust=smtp.gmail.com
spring.mail.properties.mail.smtp.auth=true
spring.mail.properties.mail.smtp.starttls.enable=true
spring.mail.properties.mail.smtp.starttls.required=true

注意,如果你已经为你的 Gmail 账户启用了2步验证,那么以上配置中的 gmail_password不应该是一个普通的密码,而应该是为你的 Google 账户生成的16个字符的应用程序密码。按照这个 链接查看详细信息并生成您的谷歌应用程序密码。

在我的例子中,我使用的是 OpenJDK,当我从 换了OracleJDK时,问题就解决了。

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

-Dmail.smtp.ssl.protocols=TLSv1.2

我看到有些人建议在创建 STMP 会话的代码中设置它,但是如果您希望在将来更新该值,则需要进行修补和部署。使用 System 属性可以在不更改代码的情况下更新它。

检查你有没有这些字段

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");

主要答案是:

props.put("mail.smtp.ssl.trust", "smtp.gmail.com");

只有在我删除以下内容之后才有效:

mail.smtp.socketFactory.class=javax.net.ssl.SSLSocketFactory