我需要将应用程序与强制使用 https 的外部 Web 服务集成。该 Web 服务的作者为我提供了 .crt 文件,我应该使用它来发出 https 请求。经过一番调查后,我发现了以下使用 KeyStore 类进行安全 https 访问的代码:
KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
FileInputStream instream = new FileInputStream(new File(file));
try {
trustStore.load(instream, password.toCharArray());
} finally {
instream.close();
}
SSLContext sslcontext =
SSLContexts.custom().loadTrustMaterial(trustStore, new TrustSelfSignedStrategy()).build();
SSLConnectionSocketFactory sslsf =
new SSLConnectionSocketFactory(sslcontext, new String[]{"TLSv1.2"}, null,
BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);
HttpClients.custom().setSSLSocketFactory(sslsf).build();
在此代码中,KeyStore 需要输入流以及密码 trustStore.load(instream, password.toCharArray())
;。但是,据我了解,我们在使用 .crt 文件时不需要密码。所以这种加载证书的方式不适合我。同时,根据我目前的发现,我在此处提供的代码是配置 HttpClient 以使用 SSL 证书的唯一方法。是否有任何解决方法来配置 HttpClient 以使用 .crt 证书?
谢谢,
安德烈
最佳答案
我假设 Web 服务正在为您提供自签名证书(即不是由知名 CA 签名的)。如果它已由 Java 的 cacerts 文件中的知名 CA 签名,则您无需执行任何操作。
否则,您有几个选择:
- 将证书导入全局 cacerts keystore
- 使用特定于应用程序的 keystore 启动您的应用程序
无论哪种情况,您首先需要将 crt 文件转换为 Java 使用的 jks keystore 。您可以通过以下方式执行此操作:
$ keytool -import -keystore mykeystore.jks -storepass horsestaple
请注意,keytool 需要提供密码(上面的 horsestaple
)才能创建 jks 存储。你可以把任何东西放在那里;正如你所说,公共(public)网站证书不需要密码保护,毕竟它们是公开的。
如果您正在执行选项 1,请备份您的 cacerts 并提供 cacerts 文件而不是 mykeystore.jks。有关 cacerts 的位置,请参阅下面的链接。对于此选项,您已准备就绪,您的应用程序应通过 HTTPS 连接到 Web 服务,无需任何其他配置,因为 Java 默认加载 cacerts。
如果您正在执行选项 2,这可能至少在测试阶段是首选,您需要使用此参数运行您的应用程序:
-Djavax.net.ssl.trustStore=mykeystore.jks
这是一个 JVM 参数,因此请适本地提供它。这取决于您运行应用程序的方式。
请注意,在这种情况下您将只有导入的证书,因此您的其他 HTTPS 连接将不起作用。您可以通过首先将标准 cacerts 复制到一个临时位置,将 key 导入其中并在上面的命令中使用它来避免这种情况。这将为您提供所有标准证书,以及您需要的证书。
选项 2 的一个小缺点是,如果添加或撤销新证书,您的应用程序特定 keystore 将不会更新。如果这是一个问题,您可以即时合并 keystore ,例如:
无论哪种情况,您现在都应该能够进行标准的 URL 提取,例如此处给出的示例:
即:
final URL url = new URL("https://example.com");
try(final InputStream in = url.openStream()){
//…
}
更多信息在这里:
- key 工具和一般证书信息
https://docs.oracle.com/cd/E19830-01/819-4712/ablqw/index.html
- 证书地点
http://docs.oracle.com/javase/7/docs/technotes/tools/solaris/keytool.html
- 导入自签名证书的更多选项
关于java - 将 KeyStore 与 .crt 一起使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38851378/