[我从JKS提取了一个密钥及其认证链,现在我正尝试使用Java将这个密钥添加到Windows密钥库中。
要加载我的JKS,我执行了以下操作:
String jksPath = "D:\\mykeystore.jks";
KeyStore keystore = KeyStore.getInstance("JKS");
FileInputStream fIn = new FileInputStream(jksPath);
keystore.load(fIn, "12345678".toCharArray());
然后我得到了密钥和认证链:
Key key = keystore.getKey("res1", "12345678".toCharArray());
Certificate[] cchain = keystore.getCertificateChain("res1");
到目前为止非常好,然后我尝试将此密钥添加到Windows Keystore:
KeyStore ks = KeyStore.getInstance("Windows-MY");
ks.load(null, null);
ks.setKeyEntry("myKey", key, "12345678".toCharArray(), cchain);
和BOOM:
线程“主”中的异常java.lang.ClassCastException:[Ljava.security.cert.Certificate;无法转换为[Ljava.security.cert.X509Certificate;在sun.security.mscapi.KeyStore.engineSetKeyEntry(KeyStore.java:402)在sun.security.mscapi.KeyStore $ MY.engineSetKeyEntry(KeyStore.java:62)在java.security.KeyStore.setKeyEntry(KeyStore.java:909)
由于setKeyEntry调用而引发的异常。
P.S:当我在JKS类型的Keystore上使用相同的语法时,不会引发异常。
似乎在sun.security.mscapi.KeyStore.engineSetKeyEntry()的实现中有一些笨拙的Java代码。它尝试将证书的[[array(“ [Ljava.security.cert.Certificate”,请注意类名中的前缀)转换为X509Certificates的array(“ [Ljava.security.cert。 X509Certificate“),这是Java从未允许您使用的简单转换表达式(例如,参见类似错误的discussion)。
我在类似情况下所做的就是将证书数组作为X509Certificate数组而不是简单的Certificate数组传递给keyStore.setKeyEntry()方法调用。