我试图通过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)。
我有这个工作的SMTP连接(不是IMAP),使用的是 com.sun.mail:javax.mail:1.5.5
和(根)证书从一个(不那么标准的)pfx-文件中加载。的属性。Session.getInstance(props)
是以下列方式构建的(也可参见API-docs------------------------)。此处 和 此处,我想你可以简单地将 smtp
与 imap
的大部分属性)。) "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 - STARTTLS
TRACE com.sun.mail.smtp.protocol - 220 Ready to start TLS
附带说一句:创建默认的 keystore 和 trustore 可以通过使用 这个 SslUtils
类、方法 loadKeyStore(null)
和 createDefaultTrustStore()
我不久前创建了这个实用类,以帮助我加载不那么标准的pfx-files)。