Java Cert Issues

2018/07/11 Java

当使用自签名证书时,Java 连接服务器时会报证书错误。在某些场景,例如测试时,又不能选择忽略证书。此时需要将自签名证书导入证书库。

Java 证书问题

当证书不被信任的时候,Java 访问 HTTPS 网站会返回:sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target

在 windows 环境下,可以用浏览器打开网站并导出证书。在 linux 下可以用 openssl 工具导出证书,注意将 {HOST} 替换为真实的域名或 ip :openssl s_client -connect {HOST}:443 -showcerts </dev/null 2>/dev/null | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > mycert.cert

可以查看下证书信息:openssl x509 -in mycert.cert -text

其中比较重要的是 CN 信息,即 Common Name,如果实际请求的域名和这个证书的 CN 信息不匹配,则会校验失败,其中 {HOST} 是你请求的域名,而 {CERTED_HOST} 是证书中的域名:

Hostname {HOST} not verified:
    certificate: sha1/MbFpSamF8kHCfea59drOuEXAMPLE
    DN: EMAILADDRESS=test, CN={CERTED_HOST}, OU=test, O=tc, , C=ChST=Guang
    subjectAltNames: []

将证书加入到 jre 的证书库中。首先获取 jre 的路径信息:

# which java
/usr/java/jdk1.8.0_51/bin/java

导入证书:keytool -import -trustcacerts -keystore /usr/java/jdk1.8.0_51/jre/lib/security/cacerts -storepass changeit -noprompt -alias mycert -file mycert.cert

如果有问题,无法重复导入同一个证书,需要删除:keytool -delete -keystore /usr/java/jdk1.8.0_51/jre/lib/security/cacerts -storepass changeit -alias mycert

忽略证书

除非是测试目的,否则不建议如此处理,容易导致中间人攻击。网上流传可以设置启动参数-Dcom.sun.net.ssl.checkRevocation=false,实测并无作用。

如果使用的是HttpsURLConnection,可以考虑在请求调用前一次性设置忽略所有证书校验:

        HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() {
            @Override
            public boolean verify(String arg0, SSLSession arg1) {
                return true;
            }
        });

License: (CC 3.0) BY-NC-SA

Search

    Table of Contents