我有一个要发布到的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 但这对我有用吗,真的那么复杂吗?
答案 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());