我正在努力解决 keytool 创建 keystore (在此处用作信任库)和导入受信任证书的方式与其他工具(例如 portecle 、 kse )执行相同操作的方式之间的行为差异.
考虑这个命令:
keytool -import -alias myAlias -file ./my_exported_server_cert.crt \
-keystore ./my_truststore.jks
这将提示我输入密码,然后创建包含证书的 my_truststore.jks
。
现在,如果我查看内部并提供正确的密码,将列出 myAlias
条目:
keytool -v -list -keystore ./my_truststore.jks -storeType jks -storepass myPass
或者,以编程方式...
try (InputStream is = new FileInputStream(new File("./my_truststore.jks"))) {
KeyStore keyStore = KeyStore.getInstance("jks");
keyStore.load(is, "myPassword".toCharArray());
Iterator<String> it = keyStore.aliases().asIterator();
while (it.hasNext()) System.out.println(it.next());
}
但是,如果我不提供密码(即从 keytool
调用中删除 storepass
参数并在出现提示时键入 return,或使用 null
作为 Java 代码中的第二个参数调用 load
),未列出任何条目。
keytool
提供警告,但未列出任何条目。
现在,如果我生成一个信任库并使用 portecle 或 kse 以相同的方式导入证书,设置密码,然后在不提供密码的情况下再次运行检查,myAlias
仍列为条目(keytool
按预期显示警告,但也显示证书)。
我对此事的有争议的理解是,密码与阅读信任库的内容不太相关(没有太多调查,我也假设这就是为什么 TrustManagerFactory#init 不接受密码, 与 KeyManagerFactory#init 相反。
我的问题
- 行为差异的原因是什么?这些工具在后台使用的核心 API 是否与
keytool
相同? - 是否有一种方法可以参数化
keytool
以生成一个信任库,允许在没有密码的情况下查询条目的读取可见性,就像其他工具一样?
注意事项
我已经使用 keytool
从以下位置复制了此行为:
- 甲骨文 JDK 11
- 甲骨文 JDK 12
- OpenJDK11
当使用 Oracle JDK8 中的 keytool
进行测试时,我注意到找到了该条目,尽管我在最初创建 keystore 服务器端并导出一个证书时收到警告:
The JKS keystore uses a proprietary format. It is recommended to migrate to PKCS12 which is an industry standard format using "keytool -importkeystore -srckeystore ./ora8_keystore.jks -destkeystore ./ora8_keystore.jks -deststoretype pkcs12"
此外,使用来自 Oracle JDK8 的 keytool
生成的信任库的 SSL 握手似乎永远挂起,没有任何失败痕迹。
在调试我的 Java 代码时,我注意到由任一工具和任一 JDK(包括 Oracle JDK8)生成的信任库最终通过工厂初始化为双格式 keystore ,而不管使用的工厂参数如何 (jks
),即 keystore 对象属于 sun.security.provider.JavaKeyStore$DualFormatJKS
类,其 spi 具有 primaryType = JKS
和 secondaryType = PCKS12
.
最后一点并不能真正帮助我理解,但它可能在某种程度上是相关的。
最佳答案
这个问题最好在open JDK bug中描述 https://bugs.openjdk.java.net/browse/JDK-8194702 . 我们还没有解决这个问题。
关于java - 如果未提供密码,则使用 keytool 创建的受密码保护的信任存储不会显示任何条目,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55478755/