【问题标题】:CertificateChain is null when importing pkcs12 (.p12) client-certificate file in Java Keystore在 Java 密钥库中导入 pkcs12 (.p12) 客户端证书文件时,CertificateChain 为空
【发布时间】:2021-09-24 14:41:33
【问题描述】:

我将带有证书链的 client-ssl-certificate KeyPair 导出为 PKCS12 文件密钥库资源管理器。我可以再次使用 KSE 加载此 PKCS12 文件,并且密钥对和证书链都在那里。当我将它加载到 java KeyStore 中时,我可以访问密钥,但证书链为空。

这是我的代码:

        final KeyStore instance = KeyStore.getInstance( "pkcs12" );
        instance.load( new ByteArrayInputStream( bytes ), password );

        instance.getKey(alias, password) => returns Key
        instance.getCertificateChain(alias) => returns null

        final KeyStore.ProtectionParameter param = new KeyStore.PasswordProtection( password );
        final KeyStore.PrivateKeyEntry privateKeyEntry = (KeyStore.PrivateKeyEntry) instance.getEntry( alias, param );

        => fails:

java.lang.NullPointerException: invalid null input
    at java.security.KeyStore$PrivateKeyEntry.<init>(KeyStore.java:524) ~[na:1.8.0_202]
    at sun.security.pkcs12.PKCS12KeyStore.engineGetEntry(PKCS12KeyStore.java:1311) ~[na:1.8.0_202]
    at java.security.KeyStore.getEntry(KeyStore.java:1521) ~[na:1.8.0_202]

通过调试我可以看到,PrivateKeyEntry 的构造函数是在链参数为空的情况下调用的:

image: debugging PrivateKeyEntry constructor call

对此我完全没有解释,也没有在互联网上找到任何信息。

我可以排除使用的别名和使用的密码作为原因。

我会感谢有关此主题的任何提示。

提前致谢,

亚历山大

【问题讨论】:

  • 您是否安装了 OpenSSL 并且可以运行openssl 命令行工具?如果是这样,请发布来自openssl pkcs12 -in /path/to/your/file.p12 -nodes 的输出。确保您不要BEGINEND 之间发布私钥的部分。这将验证您的 PKCS12 文件是否正确构建。
  • 嗨 Andrew Henle,当我这样做时,它将链输出为 PEM。对我来说似乎很好。
  • 输出中是否有PRIVATE KEY 部分?
  • 您能否使用虚拟或仅用于测试的密钥(您可以安全公开的密钥)进行复制,并提供实际的 P12 文件,可以是 base64 或 hex 等二进制保留形式,也可以是类似 pastebin 的东西?
  • @Andrew Henle,是的,私钥也输出了

标签: java authentication ssl keystore pkcs#12


【解决方案1】:

如您所见:

https://github.com/frohoff/jdk8u-jdk/blob/master/src/share/classes/java/security/KeyStore.java#L523

在以下三种情况之一中抛出异常:

  1. 您有密钥,但没有私钥。
  2. 你没有链条(就是你说的)。
  3. 你没有属性。

要确保链是问题,您可以使用激活调试

 -Djava.security.debug=all

【讨论】:

  • 我尝试使用该选项,但我没有额外的输出
  • @AlexanderM。 sun.security.util.Debug.isOn("all") 说什么?
  • 它返回错误。似乎在 intelliJ RunConfig 中传递 VM 选项不适用于 springBoot(bootRun)。我用 Gradle 设置了属性,现在它可以工作了!感谢您的提示
  • 非常感谢,我已经解决了!证书是在没有密码的情况下导出的。并且对于密码 null 被传递给 KeyStore::load 方法。传递一个空的 char 数组而不是 null 就可以了!
猜你喜欢
  • 1970-01-01
  • 2011-02-15
  • 1970-01-01
  • 1970-01-01
  • 2011-04-02
  • 2016-10-26
  • 2014-02-12
  • 2011-04-06
  • 2023-03-07
相关资源
最近更新 更多