使用带有Truststore的Java邮件StartTLS。

问题描述 投票:4回答:1

我试图通过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" 因为我希望能够控制每个访问的可信证书。

Sidenote: 我见过有人使用 "mail.imap.socketFactory.class" 来设定自己的执行情况。SocketFactory 自带 TrustManager.但当我这样做时,我的连接失败与

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

我认为这是因为设置套接字工厂实际上会使用SSL上的SMTP,而不是StartTLS(StartTLS开始时是纯文本连接,之后切换到TLS)。

java javamail starttls
1个回答
3
投票

我有这个工作的SMTP连接(不是IMAP),使用的是 com.sun.mail:javax.mail:1.5.5 和(根)证书从一个(不那么标准的)pfx-文件中加载。的属性。Session.getInstance(props) 是以下列方式构建的(也可参见API-docs------------------------)。此处此处,我想你可以简单地将 smtpimap 的大部分属性)。) "mail.transport.protocol", "smtp" "mail.smtp.host", "hostname" "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"

现在使用以下方法建立一个SSL Socket Factory com.sun.mail.util.MailSSLSocketFactory (请阅读链接中的API-docs)。MailSSLSocketFactory sslSocketFactory = new MailSSLSocketFactory("TLSv1.2"); 创建并初始化一个(默认)的 KeyManagerFactory kmf (例如,通过加载一个keystore)。创建并初始化一个(默认)的 TrustManagerFactory tmf. 呼叫 sslSocketFactory.setKeyManagers(kmf.getKeyManagers())sslSocketFactory.setTrustManagers(tmf.getTrustManagers()) 将属性 "mail.smtp.ssl.socketFactory "设置为 "mail.smtp.ssl.socketFactory"。sslSocketFactory 实例(使用 props.put(k,v)-方法)。) 注意,创建和配置的socket工厂实例是被设置的,而不是某个String或类。Javamail会直接使用设置的socket工厂实例。使用属性来创建会话。

确保正确配置了日志,并将 com.sun.mail 的日志设置为 TRACE。日志会准确地显示 "越界 "的内容,在我的例子中,会显示如下内容。DEBUG com.sun.mail.smtp - Found extension "STARTTLS", arg "" ...TRACE com.sun.mail.smtp.protocol - STARTTLSTRACE com.sun.mail.smtp.protocol - 220 Ready to start TLS

附带说一句:创建默认的 keystore 和 trustore 可以通过使用 这个 SslUtils 类、方法 loadKeyStore(null)createDefaultTrustStore() 我不久前创建了这个实用类,以帮助我加载不那么标准的pfx-files)。

© www.soinside.com 2019 - 2024. All rights reserved.