简体   繁体   English

打开默认Java信任库的最可移植的方法是什么?

[英]What is the most portable way to open the default Java truststore?

I am programmatically manipulating the default Java TrustStore. 我正在以编程方式操纵默认的Java TrustStore。 In order to do that, I need its path. 为了做到这一点,我需要它的道路。

I tried reading javax.net.ssl.keyStore and javax.net.ssl.trustStore and they're both undefined. 我尝试阅读javax.net.ssl.keyStorejavax.net.ssl.trustStore ,但它们javax.net.ssl.trustStore定义。

I came up with System.getenv("JAVA_HOME") + "/jre/lib/security/cacerts" , is it the right approach? 我想出了System.getenv("JAVA_HOME") + "/jre/lib/security/cacerts" ,这是正确的方法吗?

It works but I'd like the code to be as portable and future-proof as possible. 它可以工作,但我希望代码尽可能地可移植且面向未来。

Edits: 编辑:

  1. This is for an app running in AWS Lambda, Lamda does not allow to customize or provide your own JRE. 这是针对在AWS Lambda中运行的应用程序,Lamda不允许自定义或提供您自己的JRE。
  2. This question was originally asking for the default keystore. 这个问题最初是要求默认的密钥库。 I changed it to truststore since keystores are app-specific. 由于密钥库是特定于应用程序的,因此我将其更改为信任库。

No. You probably won't have permission to modify files in an installed JRE. 否。您可能没有权限修改已安装的JRE中的文件。 And that path does not exist, starting with Java 9. 从Java 9开始,该路径不存在。

Furthermore, as of Java 11, there is no JRE. 此外,从Java 11开始,没有JRE。 The only way to distribute an application is to use jlink to create an image containing a subset of Java SE containing only the modules required by the application. 分发应用程序的唯一方法是使用jlink创建映像,该映像包含Java SE的子集,该子集仅包含应用程序所需的模块。

In summary, you can't rely on a Java installation, and even if you find one, you can't rely on the presence of a default keystore file. 总之,您不能依赖Java安装,即使找到了Java安装,也不能依赖默认密钥库文件的存在。

You shouldn't be changing a user's Java installation anyway. 无论如何,您都不应该更改用户的Java安装。 Your code should include a custom keystore file as an application resource , which you should pass to Keystore.load : 您的代码应包括一个自定义密钥库文件作为应用程序资源 ,您应将其传递给Keystore.load

InputStream embeddedKeystore =
    MyApplication.class.getResourceAsStream("custom-keystore.pkcs");

assert embeddedKeystore != null : "Application was not properly built."
    + " Keystore is missing!";

KeyStore keystore = KeyStore.getInstance("pkcs12");
keystore.load(embeddedKeystore,
    new char[] { 's', 'w', 'o', 'r', 'd', 'f', 'i', 's', 'h' });

embeddedKeystore.close();

Posting my solution so far. 到目前为止发布我的解决方案。

In my question, I was reading from System.getenv("JAVA_HOME") + "/jre/lib/security/cacerts" but that is the path of the JDK (which isn't installed on AWS Lambda) and is the root of the /jre folder. 在我的问题中,我正在从System.getenv("JAVA_HOME") + "/jre/lib/security/cacerts"中读取内容,但这是JDK的路径(该路径未安装在AWS Lambda上),并且是/ jre文件夹。

String trustStoreLocation = Optional.ofNullable(System.getProperty("javax.net.ssl.trustStore"))
    .orElseGet(() -> System.getProperty("java.home") + "/lib/security/cacerts");

File trustStoreFile = new File(trustStoreLocation);
if (!trustStoreFile.exists()) {
    throw new RuntimeException("Unable to locate the Java TrustStore: the system property javax.net.ssl.trustStore is undefined or " + trustStoreLocation + " does not exist.");
}

KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
try (FileInputStream fis = new FileInputStream(trustStoreFile)) {
    keyStore.load(fis, new char[] { 't','h','e',' ','p','a','s','s','w','o','r','d' });
}

You can use your own path for the trustsotre and the keystore using passing system property option to the JVM 您可以使用将系统属性选项传递给JVM的方式来使用trustsotre和密钥库的路径

-Djavax.net.ssl.keyStore=your_custom_path
-Djavax.net.ssl.trustStore=your_custom_path

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM