一尘不染

在Java客户端中接受服务器的自签名ssl证书

java

它看起来像一个标准问题,但是我在任何地方都找不到清晰的方向。

我有Java代码试图连接到可能带有自签名(或过期)证书的服务器。该代码报告以下错误:

[HttpMethodDirector] I/O exception (javax.net.ssl.SSLHandshakeException) caught 
when processing request: sun.security.validator.ValidatorException: PKIX path 
building failed: sun.security.provider.certpath.SunCertPathBuilderException: 
unable to find valid certification path to requested target

据我了解,我必须使用keytool并告诉java允许这种连接是可以的。

解决此问题的所有说明均假定我完全精通keytool,例如

生成服务器的私钥并将其导入密钥库

是否有人可以发布详细说明?

我正在运行Unix,所以bash脚本是最好的。

不确定它是否重要,但是代码在jboss中执行。


阅读 378

收藏
2020-02-26

共1个答案

一尘不染

这里基本上有两个选择:将自签名证书添加到JVM信任库中,或将客户端配置为

选项1
从浏览器导出证书,并将其导入到JVM信任库中(以建立信任链):

<JAVA_HOME>\bin\keytool -import -v -trustcacerts
-alias server-alias -file server.cer
-keystore cacerts.jks -keypass changeit
-storepass changeit 

选项2
禁用证书验证:

// Create a trust manager that does not validate certificate chains
TrustManager[] trustAllCerts = new TrustManager[] { 
    new X509TrustManager() {     
        public java.security.cert.X509Certificate[] getAcceptedIssuers() { 
            return new X509Certificate[0];
        } 
        public void checkClientTrusted( 
            java.security.cert.X509Certificate[] certs, String authType) {
            } 
        public void checkServerTrusted( 
            java.security.cert.X509Certificate[] certs, String authType) {
        }
    } 
}; 

// Install the all-trusting trust manager
try {
    SSLContext sc = SSLContext.getInstance("SSL"); 
    sc.init(null, trustAllCerts, new java.security.SecureRandom()); 
    HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
} catch (GeneralSecurityException e) {
} 
// Now you can access an https URL without having the certificate in the truststore
try { 
    URL url = new URL("https://hostname/index.html"); 
} catch (MalformedURLException e) {
} 

请注意,我完全不建议使用选项2。禁用信任管理器会破坏SSL的某些部分,并使您容易受到中间攻击的攻击。首选选项1,或者甚至更好,让服务器使用由知名CA签名的“真实”证书。

2020-02-26