在Groovy中,建立URL连接时如何使用ca.pem?

时间:2019-04-08 16:06:17

标签: ssl groovy

我有一个要发布到的Web服务。使用curl我可以做到这一点:

curl --cacert ~/ca.pem [...]

效果很好。

在Groovy中,我正在这样做:

def post = new URL("$endpoint").openConnection()
post.setRequestMethod("POST")
post.setDoOutput(true)
post.setRequestProperty("Content-Type", "application/json")
post.setRequestProperty("Authorization", "Bearer $token")
post.getOutputStream().write(json.getBytes("UTF-8"))

最后一行失败:

javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target

是否有设置CA证书(这是用户可配置的路径)的简单方法?那不涉及炮击吗?

我看到了这个答案:https://stackoverflow.com/a/48173910/675083 但这对我有用吗,真的那么复杂吗?

2 个答案:

答案 0 :(得分:1)

java仅适用于密钥库。

,我猜你的ca.pem是证书。

您必须将其放入位于以下位置的标准Java ca存储中:

$JAVA_HOME/jre/lib/security/cacerts 

或者您可以使用openssl将证书转换为pkcs12密钥库,并在启动期间将其设置为java truststore:

java -Djavax.net.ssl.trustStore=path_to_pksc12 \
  -Djavax.net.ssl.trustStorePassword=changeit \
  -Djavax.net.ssl.trustStoreType=pksc12 \
  ...

但是,如果您想动态地进行操作,它将变得很复杂

答案 1 :(得分:0)

我发现此代码有效:

def nullHostnameVerifier = [
            verify: { hostname, session -> true }
        ]
        HttpsURLConnection.setDefaultHostnameVerifier(nullHostnameVerifier as HostnameVerifier)

        def is = new File(cacertPath).newInputStream() // *** how to close?

        TrustManager[] trustManagers = null;
        char[] password = null; // Any password will work.
        KeyStore caKeyStore = KeyStore.getInstance(KeyStore.getDefaultType());
        caKeyStore.load(null, password);
        CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
        Collection<? extends Certificate> certificates = certificateFactory.generateCertificates(is);
        if (certificates.isEmpty()) {
            throw new IllegalArgumentException("expected non-empty set of trusted certificates");
        }
        int index = 0;
        certificates.each {
            String certificateAlias = "ca" + Integer.toString(index++);
            caKeyStore.setCertificateEntry(certificateAlias, it);
        }
        TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
        trustManagerFactory.init(caKeyStore);
        trustManagers = trustManagerFactory.getTrustManagers();

        SSLContext sslContext = SSLContext.getInstance("SSL");
        sslContext.init(null, trustManagers, new SecureRandom());
        HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory());