将Java Mail StartTLS与Truststore一起使用

时间:2016-01-13 13:36:13

标签: java javamail starttls

我正在尝试通过Java邮件API连接到使用StartTLS和自签名证书的邮件服务器。 这似乎是一个问题,因为我找不到任何方法为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

我不想使用像"-Djavax.net.ssl.trustStore"这样的虚拟机参数,因为我希望每次访问都能控制可信证书。

旁注:我看到人们使用"mail.imap.socketFactory.class"设置自己SocketFactory的自定义TrustManager实现。 但是当我这样做时,我的连接失败了

javax.net.ssl.SSLException: Unrecognized SSL message, plaintext connection?

我认为这是因为设置套接字工厂实际上将使用SMTP over SSL而不是StartTLS(以纯文本连接方式启动并稍后切换到TLS)。

1 个答案:

答案 0 :(得分:1)

我使用com.sun.mail:javax.mail:1.5.5和(根)证书从(不是那么标准的)pfx文件加载的SMTP连接(不是IMAP)。提供给Session.getInstance(props)的属性按以下方式构建(另请参阅API文档herehere,我认为您只需将smtp替换为imap对于大多数属性):

" 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"," true"

现在使用com.sun.mail.util.MailSSLSocketFactory构建SSL套接字工厂(阅读链接中的API-docs):
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) - 方法)。请注意,已设置已创建和配置的套接字工厂实例,而不是某些String或类。 Javamail将直接使用set socket工厂实例。
使用属性创建会话。

确保已正确配置日志记录并将其设置为TRACE for 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

旁注:创建默认密钥库和信任可以使用this SslUtils类,方法loadKeyStore(null)createDefaultTrustStore()完成(我之前创建了这个实用程序类来帮助我加载不那么标准的pfx文件。)