【发布时间】:2019-04-02 15:45:16
【问题描述】:
我正在努力解决 keytool 创建密钥库(在此处用作信任库)和导入受信任证书的方式与其他工具(例如 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 调用load Java 代码中的第二个参数),没有列出任何条目。
keytool 提供警告,但不列出任何条目。
现在,如果我生成信任库并使用 portecle 或 kse 以相同的方式导入证书,设置密码,然后在不提供密码的情况下再次运行检查,myAlias 仍被列为条目 (keytool按预期显示警告,但也显示证书)。
我对此事有争议的理解是密码与读取信任存储的内容不太相关(没有太多调查,我也假设这就是TrustManagerFactory#init 不使用密码的原因,与KeyManagerFactory#init相反)。
我的问题
- 行为差异的原因是什么?这些工具不是在幕后使用与
keytool相同的核心 API 吗? - 有没有一种方法可以对
keytool进行参数化,以生成信任存储,在没有密码的情况下查询条目时允许读取可见性,就像其他工具一样?
备注
我已经用keytool 复制了这种行为:
- Oracle JDK 11
- Oracle JDK 12
- OpenJDK11
在使用 Oracle JDK8 中的 keytool 进行测试时,我注意到找到了该条目,尽管在最初创建密钥库服务器端并导出一个证书时收到警告:
JKS 密钥库使用专有格式。建议 迁移到使用“keytool”的行业标准格式 PKCS12 -importkeystore -srckeystore ./ora8_keystore.jks -destkeystore ./ora8_keystore.jks -deststoretype pkcs12"
此外,使用来自 Oracle JDK8 的 keytool 生成的信任库的 SSL 握手似乎永远挂起,没有任何失败的痕迹。
在调试我的 Java 代码时,我注意到由任一工具和任一 JDK(包括 Oracle JDK8)生成的信任库最终通过工厂初始化为双格式密钥库,而不管使用的工厂参数如何 (jks),即密钥库对象属于sun.security.provider.JavaKeyStore$DualFormatJKS 类,SPI 具有primaryType = JKS 和secondaryType = PCKS12。
最后一点并不能真正帮助我理解,但它可能以某种方式相关。
【问题讨论】:
-
这不是我 20 多年的经验。
-
@user207421 它应该很容易复制。你试过具体的场景吗?
-
我已经指出,我已经做了 20 多年的所有这些事情。如果不提供密码,您得到的只是 (1) 无法访问私钥和 (2) 未验证密钥库结构。
-
@user207421 这就是我希望它工作的方式,是的。然而,当使用 keytool 创建信任库并使用 keytool 导入证书时,我可以使用
keytool list或以编程方式复制“丢失的条目”部分,至少使用 java 11 及更高版本。 -
我有一个类似的问题,如果你找到了答案,请告诉我。我的问题只是信任库之一没有列出其中没有密码的所有证书。当我用正确的密码列出它时,它会正确列出内容。
标签: java keytool truststore