Java 仅使用 CA 证书且无密钥库使用 SSLContext

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18513792/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 08:42:11  来源:igfitidea点击:

Using SSLContext with just a CA certificate and no keystore

javasslkeystorecajersey-client

提问by Remo

I need to setup a javax.net.ssl.SSLContextfor use in a Jersey-Client application. All I want to do is the context to accept a custom root ca certificate. Is is really true that there is no way around of generating a keystore file and importing the CA certificate?

我需要设置一个javax.net.ssl.SSLContext用于 Jersey 客户端应用程序。我想要做的就是接受自定义根 ca 证书的上下文。真的没有办法生成密钥库文件并导入 CA 证书吗?

采纳答案by Bruno

Is is really true that there is no way around of generating a keystore file and importing the CA certificate?

真的没有办法生成密钥库文件并导入 CA 证书吗?

There are way to do it without a keystore file, but since you would have to load the CA certificate you want to trust one way or another, you'll have to load a file or resource somehow.

有一些方法可以在没有密钥库文件的情况下执行此操作,但是由于您必须以一种或另一种方式加载您想要信任的 CA 证书,因此您必须以某种方式加载文件或资源。

(You could also certainly implement your own TrustManagerthat makes all the calls to use the Certification Path API, without using the KeyStoreAPI at all, but that would only increase the complexity of your code, not reduce it. You would also need to understand the Java PKI Programmer's Guideto do this correctly.)

(您当然也可以实现自己的TrustManager所有调用以使用认证路径 API,KeyStore根本不使用API,但这只会增加代码的复杂性,而不是减少它。您还需要了解Java PKI 程序员指南以正确执行此操作。)

If you really don't want a keystore file, you could use the KeyStoreAPI in memory and load the certificate directly.

如果您真的不想要密钥库文件,您可以使用KeyStore内存中的API 并直接加载证书。

Something along these lines should work (not tested):

沿着这些路线的东西应该工作(未测试):

InputStream is = new FileInputStream("cacert.crt");
// You could get a resource as a stream instead.

CertificateFactory cf = CertificateFactory.getInstance("X.509");
X509Certificate caCert = (X509Certificate)cf.generateCertificate(is);

TrustManagerFactory tmf = TrustManagerFactory
    .getInstance(TrustManagerFactory.getDefaultAlgorithm());
KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
ks.load(null); // You don't need the KeyStore instance to come from a file.
ks.setCertificateEntry("caCert", caCert);

tmf.init(ks);

SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, tmf.getTrustManagers(), null);

(Remember to close everything and handle the exceptions.)

(记住关闭所有内容并处理异常。)

Whether loading the certificate this way or loading the certificate into a similar KeyStoreinstance from a keystore file is more convenient is up to you to decide.

以这种方式加载证书还是将证书KeyStore从密钥库文件加载到类似的实例中更方便由您决定。