11

I need to generate a java keystore, using java 11, and be able to use it in both java 8 and java 11. I'm using format PKCS12. For some reason, when I generate it, using keytool from java 11, the keytool from java 8 can't open it.

Generating using java 11

(java 11)$ keytool -genkeypair -keyalg RSA -noprompt -alias key -dname "CN=hostname, OU=XX, O=XX, L=YY, S=CZ, C=CZ" -keystore file.p12 -storepass password -keypass password -deststoretype pkcs12

For java 11 the keystore is fine and working. But if I try to read it using java 8

(java 8)$ keytool -list -keystore file.p12 
keytool error: java.io.IOException: Invalid keystore format

Why is this happening? I thought PKCS12 is a standardized format, and should be universal. But for some reason it's not working even between java versions.

I was able to solve this issue by switching keytool to legacy generating, using switch -J-Dkeystore.pkcs12.legacy.

I want to change my project to generate keystore in code. Something like:

KeyStore ks = KeyStore.getInstance("pkcs12");
ks.load(null, password);
ks.setKeyEntry(keyAlias, keyPair.getPrivate(), password, certChain);
ks.store(output, password);

But I've encountered same issue. If I generate it in java 11, then java 8 is not able to open it (not using keytool neither in java code). Is there a way to make KeyStore class to generate keystore in "compatible" format? Or any other way to generate a keystore in code, so it is compatible?

Martin Ocenas
  • 125
  • 1
  • 6
  • 1
    [This blog post](https://blogs.oracle.com/jtc/jdk9-keytool-transitions-default-keystore-to-pkcs12) suggests that PKCS12 was only introduced as the format in Java 9 and that previous versions used something called "JKS" (which I assume is a Java-specific format). – Joachim Sauer Aug 18 '21 at 08:50
  • 1
    Java 8 already supports PKCS12 but it is not the default format. If you want to use a PKCS12 keystore with Java 8 you need to pass the parameter "-storetype pkcs12" (see https://docs.oracle.com/javase/8/docs/technotes/tools/unix/keytool.html#keytool_option_list) and https://stackoverflow.com/a/11540061/5646962 – Thomas Kläger Aug 18 '21 at 10:03
  • 3
    Using `-storetype pkcs12` does not help. `(java 8)$ keytool -list -keystore store.p12 -storetype pkcs12` Ends with `keytool error: java.io.IOException: parseAlgParameters failed: ObjectIdentifier() -- data isn't an object ID (tag = 48)` – Martin Ocenas Aug 19 '21 at 08:56
  • 1
    Also java 8 and it's keytool can open a PKCS12 keystore (and output says `Keystore type: PKCS12` - so java 8 probably has support for it) if it was generated by java 8 but not if it was generated by java 11. – Martin Ocenas Aug 19 '21 at 09:01
  • @MartinOcenas , I am facing the same issue. Any update on the solution which worked ? – ysn Sep 09 '21 at 08:54
  • @ysn Not yet. So far we stick with the solution using external `keytool` and optin `-J-Dkeystore.pkcs12.legacy`. It's far from ideal, but it works. – Martin Ocenas Sep 10 '21 at 11:34
  • 2
    I bet you're using 11.0.12 or higher and 8 below 8u301. 11.0.12 up (and 16 up) default to a new stronger encryption in PKCS12 https://www.oracle.com/java/technologies/javase/11-0-12-relnotes.html#JDK-8153005 but this uses PBES2 format and 8 below 8u301 doesn't handle that correctly https://bugs.openjdk.java.net/browse/JDK-8202837 – dave_thompson_085 Dec 06 '21 at 14:21
  • Did not you try System.getProperties().setProperty("keystore.pkcs12.legacy", ""); ? – Leonid Sep 24 '22 at 23:45

1 Answers1

-1

If you are running with Java 8 , then change like below

KeyStore ks = KeyStore.getInstance("JKS");