将Java Mail StartTLS与信任库一起使用
我正在尝试连接到一个邮件服务器,该服务器使用StartTLS,并通过javamailapi使用自签名证书。 这似乎是个问题,因为我找不到任何方法来为StartTLS设置可接受的证书或信任库将Java Mail StartTLS与信任库一起使用,java,jakarta-mail,starttls,Java,Jakarta Mail,Starttls,我正在尝试连接到一个邮件服务器,该服务器使用StartTLS,并通过javamailapi使用自签名证书。 这似乎是个问题,因为我找不到任何方法来为StartTLS设置可接受的证书或信任库 Properties props = new Properties(); props.put("mail.imap.starttls.enable", "true"); props.put("mail.imap.starttls.required", "true"); Session session = Se
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”
这样的VM参数,因为我希望能够控制每次访问的受信任证书
旁注:我见过人们使用“mail.imap.socketFactory.class”
设置自己的socketFactory
实现,并使用自定义的TrustManager
。
但是当我这样做的时候,我的连接就失败了
javax.net.ssl.SSLException: Unrecognized SSL message, plaintext connection?
我认为这是因为设置套接字工厂实际上将使用SSL上的SMTP,而不是StartTLS(它以纯文本连接开始,稍后切换到TLS)。我使用
com.sun.mail:javax.mail:1.5.5
和从(非标准)加载的(root)证书为SMTP连接(而非IMAP)实现了这一点pfx文件。提供给Session.getInstance(props)
的属性是以以下方式构建的(另请参见API文档,我认为对于大多数属性,您可以简单地将smtp
替换为imap
):
“邮件.传输.协议”,“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” 现在使用(阅读链接中的API文档)构建SSL套接字工厂:
mailssocketfactory-sslSocketFactory=新的mailssocketfactory(“TLSv1.2”)代码>
创建并初始化(默认)KeyManagerFactory kmf
(例如,通过加载密钥库)。
创建并初始化(默认)TrustManagerFactoryTMF
。
调用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-找到扩展名“STARTTLS”,arg”“
。。。
TRACE com.sun.mail.smtp.protocol-STARTTLS
TRACE com.sun.mail.smtp.protocol-220准备启动TLS
另一方面:可以使用类、方法loadKeyStore(null)
和createDefaultTrustStore()
创建默认密钥库和信任库(我不久前创建了这个实用程序类,以帮助我加载不太标准的pfx文件)。除上述方法外,只需将属性设置为您想要信任的主机的名称,就可以简化这一过程。或者,您可以使用该程序将自签名证书从服务器加载到默认的信任存储中。我使用的是Java mail的1.3版本,必须升级才能获得MailSSLSocketFactory。工作起来很有魅力。