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参数并在提示时键入返回,或在Java代码中将null作为第二个参数调用load),则不会列出任何条目。
keytool提供警告,但不列出任何条目。
现在,如果我使用portecle或kse以相同的方式生成信任存储并导入证书,设置密码,并在不提供密码的情况下再次运行检查,则myAlias仍将被列为条目(keytool按预期显示警告,但也显示证书)。
我对此问题的理解是,在读取信任存储区的内容时,密码不太相关(没有进行太多调查,因此我也假设这就是为什么TrustManagerFactory#init不需要密码,与KeyManagerFactory#init相反)。
我的问题
- 这种行为差异的原因是什么?这些工具不是使用与幕后的
keytool相同的核心API吗? - 是否有一种方法可以将
keytool参数化,以生成允许在没有密码的情况下查询条目时具有读取可见性的信任存储区,就像其他工具一样?
注
我已经使用以下keytool复制了此行为:
- Oracle JDK 11(甲骨文JDK 11)
- Oracle JDK 12(甲骨文JDK 12)
- OpenJDK11(开放式JDK 11)
在使用来自Oracle JDK8的keytool进行测试时,我注意到找到了条目,尽管在最初创建服务器端密钥库以及导出一个证书时会收到警告:
JKS密钥库使用专有格式。建议迁移到PKCS12,这是一种使用“keytool -importkeystore -srckeystore ./ora8_keystore.jks -destkeystore ./ora8_keystore.jks -deststoretype pkcs12”命令的行业标准格式。
此外,使用来自Oracle JDK8的keytool生成的信任库进行SSL握手似乎会永远挂起,没有失败的痕迹。
jks),即密钥库对象是sun.security.provider.JavaKeyStore$DualFormatJKS类的,具有spi,其primaryType = JKS和secondaryType = PCKS12。最后一部分并没有真正帮助我理解,但它可能在某种程度上是相关的。
keytool list或以编程方式创建信任存储并使用keytool导入证书时,至少在Java 11及以上版本中,我仍然可以复制“缺少条目”的部分。 - Mena