当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) {
//...
}
但这会导致安全漏洞。我想也许这比在这种情况下发送未加密的数据更好?
答案 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',那就告诉你设置那个系统属性。