JavaMail:端口 25 上的 TLS 可以使用单独的信任库吗?
我正在尝试使用 TLS 在端口 25(无 SSL)上使用 JavaMail 发送邮件,但使用我自己的信任库(因为原始 cacerts 信任库不包含所需的证书,并且我不想修改 Java 的默认信任库) 。 我有代码能够使用系统信任库通过 TLS 发送邮件,通过设置
mail.smtp.starttls.enable=true
设置
System.setProperty("javax.net.ssl.trustStore", ...)
属性,还可以在连接安全时 为指向正确的信任库。由于它是普通端口 25,因此我也不需要设置任何 socketFactory 属性(和实现)。我可以使用系统信任库在端口 25 上使用 TLS 发送邮件。
然而..切换系统属性以便能够设置正确的信任存储有点愚蠢,尤其是在服务器上,当我不知道其他代码想要发送邮件并且可能还需要使用系统属性时,一般:我正在寻找另一种解决方案,既不修改系统信任库(cacerts文件,制作它的副本并修改副本是可以的!),也不修改当前设置它所需的系统属性。
我已经尝试过:
设置我自己的 SSL socketFactory 并使用我自己的密钥管理器加载另一个信任库。当不需要在端口 25 上发送但我已经可以在端口 465 上启动安全连接时,这绝对是完美的。但是..我不能这样做,这样做最终会导致套接字异常,因为我我正在尝试安全地连接到不受保护的邮件服务器。
尝试设置我自己的socketFactory,但使用普通套接字进行实际通信。这基本上与根本不使用我自己的 socketFactory 相同,最终使用系统 cacerts trustStore 文件使用 Java。
修改cacerts系统信任库文件。这可行,但我不想修改系统的信任存储,我可能没有写入权限或可以修改密钥存储密码等。
修改
“javax.net.ssl.trustStore "
系统属性指向我自己的信任库文件。工作得很好,但我也不想修改系统属性,因为我的代码在服务器上运行,我不知道还有哪些其他代码在那里运行并且需要完整的属性。即使保存以前的状态并恢复并不能真正防止其他线程在修改时使用此属性,因此我不太喜欢这个解决方案。
简而言之:有谁知道如何在端口 25 上使用与邮件服务器的非安全连接、打开 TLS(通过设置邮件属性)的解决方案,这在内部保护连接并使用我自己的信任库文件无需修改证书或系统属性?也许有一种与 socketFactory 属性类似的方法,仅在非安全连接变得安全时才使用?
I'm trying to send mail using JavaMail on port 25 (no SSL) using TLS but with my own truststore (because the original cacerts truststore does not contain the needed certificates and I don't want to modify the default trust store of Java).
I have code that is able to send a mail using TLS using the system truststore, by setting up the
mail.smtp.starttls.enable=true
property, also, setting up
System.setProperty("javax.net.ssl.trustStore", ...)
to point to the correct truststore when the connection goes secure works. Since its the normal port 25, I don't need to setup any socketFactory properties (and implementations) either. I can send mails using TLS on port 25 using the system truststore.
However.. switching system properties to be able to set up the correct trust store is kinda silly, especially on a server, when I don't know what other code wants to send mail and maybe needs to use the system properties as well, in general: I am searching for another solution neither to modify the system truststore (the cacerts file, making a copy of it and modify the copy is okay though!) nor the system properties currently needed to set it up.
What I tried already:
Setting up my own SSL socketFactory and using my own key manager to load another truststore. This would work absolutely perfect when there wasn't a need to send on port 25 but instead I could already start a secure connection on port 465. However.. I can't do that, doing that ends up with a socket exception because I'm trying to securely connect to the mail server which isn't protected though.
Trying to set up my own socketFactory, but using a normal socket for the actual communication. That basically is the same as not using my own socketFactory at all and ends up with Java using the system cacerts trustStore file.
modifying the cacerts system truststore file. This works, but I don't want to modify the trust store of the system, I might not have write permissions or the keystore password could be modified, etc.
modifying the
"javax.net.ssl.trustStore"
system property to point to my own truststore file. Works nicely, but I don't want to modify System properties either, because my code runs on a server and I don't know what other code runs there and needs the properties intact. Even saving the former state and restoring doesn't really guard against other threads using this property at the time its modified, so I don't really like this solution.
So.. in short: does anyone know a solution how I can use a non safe connection to a mail server on port 25, switch on TLS (by setting up the mail property), this internally secures the connection and using my own truststore file without modiying cacerts or a system property? Maybe there is a similar way to the socketFactory properties which is only used when the non-safe connection goes secure?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
使用 -Djavax.net.ssl.trustStore=... 启动您的应用程序,
然后它将仅与您的 java 应用程序相关,而与其他系统属性无关。
Start your application with -Djavax.net.ssl.trustStore=...
Then it will only be relevant to your java application and no other system properties.
哎呀..发现了..有两个socketFactory属性可以传递..一个用于SSL,另一个用于非ssl工厂..
Whoops.. found it.. there's two socketFactory properties that can be passed.. one for SSL, the other one for non-ssl factories..