我正在尝试连接到一个使用StartTLS的邮件服务器,该服务器通过Java使用具有自签名证书的证书。这似乎是个问题,因为我找不到任何方法为StartTLS设置可接受的证书或信任库。
Properties props = new Properties();
props.put("mail.imap.starttls.enable", "true");
props.put("mail.imap.starttls.required", "true");
Session session = Session.getInstance(props);
Store store = session.getStore("imap");
store.connect(hostName, port, userName, userPassword);当我按原样运行我的应用程序时,我会得到这个PKIX路径错误:
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我不喜欢使用VM参数,比如"-Djavax.net.ssl.trustStore",因为我希望能够控制每次访问的受信任证书。
Sidenote:我见过人们使用"mail.imap.socketFactory.class"来使用自定义的TrustManager设置自己的SocketFactory实现。但是当我这样做的时候我的连接失败了
javax.net.ssl.SSLException: Unrecognized SSL message, plaintext connection?我认为这是因为设置套接字工厂实际上将在SSL上使用SMTP而不是StartTLS (StartTLS从纯文本连接开始,稍后切换到TLS )。
发布于 2016-01-13 18:04:39
我使用从pfx文件加载的com.sun.mail:javax.mail:1.5.5和(root)证书来处理SMTP连接(而不是IMAP)。提供给Session.getInstance(props)的属性是以以下方式构建的(还请参阅API-docs 这里和这里,我认为大多数属性可以简单地用imap替换smtp ):
"mail.transport.protocol“"smtp”
"mail.smtp.host",“主机名”
"mail.smtp.port","25“
"mail.smtp.connecttimeout","5000“// 5秒
"mail.smtp.timeout","50000“/50秒
"mail.smtp.ssl.protocols","TLSv1.2“
"mail.smtp.starttls.required",“真”
现在使用com.sun.mail.util.MailSSLSocketFactory构建一个Socket (阅读链接中的API):
MailSSLSocketFactory sslSocketFactory = new MailSSLSocketFactory("TLSv1.2");
创建(默认) KeyManagerFactory kmf并使其不适当(例如,通过加载密钥存储库)。
创建(默认) TrustManagerFactory tmf并使其不适当化。
调用sslSocketFactory.setKeyManagers(kmf.getKeyManagers())和sslSocketFactory.setTrustManagers(tmf.getTrustManagers())
将属性"mail.smtp.ssl.socketFactory“设置为sslSocketFactory实例(使用props.put(k,v)-method)。请注意,已创建和配置的套接字工厂实例已设置,而不是某些字符串或类。Javamail将直接使用set套接字工厂实例。
使用这些属性创建会话。
确保正确配置了日志记录,并将其设置为com.sun.mail跟踪。日志记录准确地显示了什么是“越界”,在我的例子中显示了例如:
DEBUG com.sun.mail.smtp - Found extension "STARTTLS", arg ""
..。
TRACE com.sun.mail.smtp.protocol - STARTTLS
TRACE com.sun.mail.smtp.protocol - 220 Ready to start TLS
另外,还可以使用SslUtils类、方法loadKeyStore(null)和createDefaultTrustStore()来创建默认的密钥存储库和信任库(我不久前创建了这个实用程序类,以帮助加载不那么标准的pfx-文件)。
https://stackoverflow.com/questions/34768136
复制相似问题