简体   繁体   English

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

[英]In Groovy, how do you use a ca.pem when making a URL connection?

I have a web service I want to POST to.我有一个要发布到的 Web 服务。 With curl I can do this:使用 curl 我可以做到这一点:

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

which works fine.这工作正常。

In Groovy I'm doing this:在 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"))

That last line fails with:最后一行失败:

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

Is there a simple way of setting my ca cert (which is a user configurable path)?有没有一种简单的方法来设置我的 ca 证书(这是一个用户可配置的路径)? That doesn't involve shelling out?这不涉及炮轰吗?

I saw this answer: https://stackoverflow.com/a/48173910/675083 But is that relevant to me and is it really that complicated?我看到了这个答案: https : //stackoverflow.com/a/48173910/675083但这与我有关吗,真的那么复杂吗?

java works only with keystores. Java仅适用于密钥库。

and your ca.pem I guess is a certificate. 我猜你的ca.pem是证书。

you have to put it into standard java ca-store located here: 您必须将其放入位于以下位置的标准java ca存储中:

$JAVA_HOME/jre/lib/security/cacerts 

or you could convert your certificate into pkcs12 keystore with openssl and set it as java truststore during startup: 或者您可以使用openssl将证书转换为pkcs12密钥库,并在启动期间将其设置为java truststore:

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

but if you want to do it dynamically it'll be so complicated as you've found 但是如果您想动态地进行操作,就会发现它是如此复杂

I found this code that worked: 我发现此代码有效:

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());

Bit late but I was searching for something similar and I think there is a middle ground that allows you to dynamically use your ca certificate and isn't too horrible Essentially you want to trust the CA so you need to tell Groovy to trust it.有点晚了,但我正在寻找类似的东西,我认为有一个中间立场,它允许您动态使用您的 ca 证书,并且不会太可怕基本上您想要信任 CA,因此您需要告诉 Groovy 信任它。

As above java deals in keystores so your first step should be to add the pem file to a keystore如上所述,java 处理密钥库,因此您的第一步应该是将 pem 文件添加到密钥库

keytool -import -alias somealias -keystore ca.jks -file ca.pem

(this assumes your pem is a single certificate with no headers etc. but if not there are plenty of guides on how to add certificate to a keystore). (这假设您的 pem 是一个没有标题等的单个证书,但如果不是,则有很多关于如何将证书添加到密钥库的指南)。

Then you need to create an SSLContext and load your ketystore然后你需要创建一个SSLContext并加载你的ketystore

import javax.net.ssl.SSLContext
import javax.net.ssl.TrustManagerFactory
import java.security.KeyStore

def context = SSLContext.getInstance('SSL')
def tks = KeyStore.getInstance(KeyStore.defaultType);
def tmf = TrustManagerFactory.getInstance('SunX509')

new File ("/path/to/ca.jks").withInputStream { stream ->
  tks.load(stream, "password".toCharArray())
}
tmf.init(tks)
context.init(null, tmf.trustManagers, null)

Then finally get your connection to use the context然后最后让您的连接使用上下文

def post = new URL("$endpoint").openConnection()
post.setSSLSocketFactory(context.socketFactory)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Docker 机器:找不到 ca.pem - Docker-machine : ca.pem not found 在delphi中将ca.pem文件的内容作为硬编码字符串提供给SSL连接 - Giving the content of ca.pem file as hard coded string in delphi for SSL connection 在哪里可以下载用于boost :: asio :: ssl的ca.pem文件? - Where can I download a ca.pem file for boost::asio::ssl? 与Java建立连接时,是否需要在VM TrustStore中添加经过验证的CA? - Do we need to add the verified CA in VM TrustStore when making connection from java? 如何将 Apple KeyChain 中的所有 CA 证书导出到单个 PEM 包中? - How do I export all CA certificates from Apple KeyChain into a single PEM bundle? 使用特定的CA进行SSL连接 - Use a particular CA for a SSL connection 如何根据给定的csr,key,pem和crt创建密钥库 - How do you create a keystore given csr, key, pem and crt 如何向 k8s 添加证书颁发机构 (CA)? - How do you add a certificate authority (CA) to k8s? 如何删除 fiddler 安装的根 CA 证书 - How do you remove the root CA certificate that fiddler installs 当您的CA不被系统信任时,如何将Android应用程序连接到SSL服务器? - How to connect Android Application to SSL server when you have a CA that isn't trusted by the system?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM