SMTP STARTTLS:如果远程SMTP服务器具有自签名证书,如何表现?

时间:2014-03-09 13:05:33

标签: java ssl smtp starttls

当SMTP客户端连接到远程SMTP服务器并发出具有自签名证书的STARTTLS命令时 - 我在客户端收到错误:

  

javax.net.ssl.SSLHandshakeException:   sun.security.validator.ValidatorException:PKIX路径构建失败:   sun.security.provider.certpath.SunCertPathBuilderException:无法   找到所请求目标的有效证书路径

有一种解决方案可以信任所有证书,如:

SSLContext trustAllSSLContext;

TrustManager[] trustAllCerts = new TrustManager[]{new X509TrustManager() {

                @Override
                public X509Certificate[] getAcceptedIssuers() {
                    return null;
                }

                @Override
                public void checkClientTrusted(X509Certificate[] certs, String authType) {
                }

                @Override
                public void checkServerTrusted(X509Certificate[] certs, String authType) {
                }
            }};

            try {
                trustAllSSLContext = SSLContext.getInstance("SSL");
                trustAllSSLContext.init(null, trustAllCerts, null);
            } catch (NoSuchAlgorithmException | KeyManagementException ex) {
                //...
            }

但这会导致安全漏洞。我想也许这比在这种情况下发送未加密的数据更好?

1 个答案:

答案 0 :(得分:1)

与未加密的相比,它确实可以防止只能窃听的被动攻击者,而不是活跃的攻击者。

基本上是How to handle invalid SSL certificates with Apache HttpClient?的副本,但包含了一些你不需要的内容。

当然,最好的方法是让服务器获得“真正的”证书。如果没有这个,要信任他们的自签名证书而不是任何其他人,请通过某些流程获得他们的证书,确保不会被篡改并将其放入您的信任库。

如果这是个人计算机或Java的个人安装,则JSSE默认信任库是文件JRELOC / lib / security / jssecacerts(如果存在),否则为SAME / cacerts。 cacerts文件包含在Java包中,包括几十个着名的公共CA,如Verisign,GoDaddy等,因此您对互联网上几乎所有公共主机(使用这些CA)的连接都可以使用,但您可以添加根据需要删除或删除。在这种情况下,在文件中以DER或PEM格式获取所需的证书,并且:

keytool -keystore JRELOC/lib/security/cacerts -importcert -file the_added_cert 
# or JRELOC/bin/keytool if that directory isn't in your search path
# enter changeit for the password, and confirm that you want to trust this cert

如果此(机器和)Java与其他用户共享,则更改默认信任库也会影响它们。如果您或他们不希望这样,请创建您自己的文件(通过复制标准文件并进行修改),然后通过使用-Djavax.net.ssl.trustStore = filename运行程序来使用该信任库(如{{3中所述)或者如果你不自己运行'java',那就告诉你设置那个系统属性。