0

I extracted a Key and its certification chain from a JKS, and now I'm trying to add this key to the Windows Keystore using Java.

To load my JKS I did the following:

    String jksPath = "D:\\mykeystore.jks";
    KeyStore keystore = KeyStore.getInstance("JKS");
    FileInputStream fIn = new FileInputStream(jksPath);
    keystore.load(fIn, "12345678".toCharArray());

Then I get the key and the certification chain:

    Key key = keystore.getKey("res1", "12345678".toCharArray());
    Certificate[] cchain = keystore.getCertificateChain("res1");

So far so good, then I try to add this key to my Windows Keystore:

    KeyStore ks = KeyStore.getInstance("Windows-MY");
    ks.load(null, null);
    ks.setKeyEntry("myKey", key, "12345678".toCharArray(), cchain);

And BOOM:

Exception in thread "main" java.lang.ClassCastException: [Ljava.security.cert.Certificate; cannot be cast to [Ljava.security.cert.X509Certificate; at sun.security.mscapi.KeyStore.engineSetKeyEntry(KeyStore.java:402) at sun.security.mscapi.KeyStore$MY.engineSetKeyEntry(KeyStore.java:62) at java.security.KeyStore.setKeyEntry(KeyStore.java:909)

Exception thrown due to the setKeyEntry call.

P.S: when I use the same syntaxe on a JKS type of Keystore no exception is thrown.

Cœur
  • 37,241
  • 25
  • 195
  • 267
TheByeByeMan
  • 1,396
  • 2
  • 28
  • 50

1 Answers1

3

It seems there's a clumsy bit of java code in the implementation of sun.security.mscapi.KeyStore.engineSetKeyEntry(). It tries to convert an array of Certificates ("[Ljava.security.cert.Certificate", notice the prefix in the class name) to an array of X509Certificates (" [Ljava.security.cert.X509Certificate"), which is not something java ever allows you to do with a simple cast expression (e.g. see discussion of a similar mistake).

All I did in a similar situation is to pass the certificate array to the keyStore.setKeyEntry() method call as a X509Certificate array, rather than a simple Certificate array.

Community
  • 1
  • 1