Tuesday, October 15, 2019

Identifying and handling Java keystore store types in different Java versions

Recently I encountered a different behaviour of Java keytool in newer versions of Java (I tested 10.0.2 and 11.0.4) compared to older versions (I tested 7.0_131 and 8.0_144) in regards to identifying store types.

Generate keystore with various store types

keytool is able to handle three different store types.
Basically I am running these commands (regardless which Java version is in place). Store types are not case sensitive.
keytool -genkey -alias foo -keystore a.keystore -storetype JKS
keytool -genkey -alias foo -keystore b.keystore -storetype JCEKS
keytool -genkey -alias foo -keystore c.keystore -storetype PKCS12

In detail:
I supply a password and simply hit Enter to all the questions being asked except the last one (answer y). I also don't provide a different key password.
Note that the default store type has also changed between Java versions (JKS in Java 8, PKCS12 in Java 10) so running the above commands without -storetype .. will generate keystores of different type resp. to your Java version in use. It is best to always indicate a store type in order to avoid any disambiguity.

keytool -genkey -alias foo -keystore a.keystore -storetype jks
Enter keystore password:
Re-enter new password:
What is your first and last name?
...
Is CN=Unknown, OU=Unknown, O=Unknown, L=Unknown, ST=Unknown, C=Unknown correct?
  [no]:  y

Enter key password for 
        (RETURN if same as keystore password):

Checking the keystore type via keytool -list

Since keytool -list ... also indicates the store type (before listing the aliases) I am running
keytool -list -keystore a.keystore
keytool -list -keystore b.keystore
keytool -list -keystore c.keystore

Result for Java 7 and 8

keytool -list -keystore a.keystore
Enter keystore password:

Keystore type: JKS
Keystore provider: SUN

Your keystore contains 1 entry

foo, Oct 15, 2019, PrivateKeyEntry,
Certificate fingerprint (SHA1): 69:B0:E2:F8:D4:C3:77:70:A2:20:AC:BE:51:B1:6A:FF:71:85:AF:4F
keytool -list -keystore b.keystore
keytool error: java.io.IOException: Invalid keystore format

keytool -list -keystore c.keystore
keytool error: java.io.IOException: Invalid keystore format

i.e. keytool does not recognize the store type in Java 7 and 8
If you want to see the list of aliases you need to know the store type in advance and indicate it on the command line.

keytool -list -keystore b.keystore -storetype JCEKS
Enter keystore password:

Keystore type: JCEKS
Keystore provider: SunJCE

Your keystore contains 1 entry

foo, Oct 15, 2019, PrivateKeyEntry,
Certificate fingerprint (SHA1): 87:08:88:32:20:F2:61:11:C3:82:E0:DF:26:76:7B:8A:CD:2C:2C:B8
keytool -list -keystore c.keystore -storetype PKCS12
Enter keystore password:

Keystore type: PKCS12
Keystore provider: SunJSSE

Your keystore contains 1 entry

foo, Oct 15, 2019, PrivateKeyEntry,
Certificate fingerprint (SHA1): E8:C4:B1:F2:E2:C9:7F:9F:D0:10:77:3D:F5:07:30:77:3C:E3:74:8D

Result for Java 10 and 11

The newer Java versions are able to list any store type.
keytool -list -keystore a.keystore
Enter keystore password:

Keystore type: JKS
Keystore provider: SUN

Your keystore contains 1 entry

foo, Oct 15, 2019, PrivateKeyEntry,
Certificate fingerprint (SHA-256): 25:EB:EE:65:AC:AD:F5:44:58:90:82:E3:BE:9D:A2:AD:D0:EC:91:50:CB:72:75:C9:03:12:0F:58:4F:A5:FA:44

Warning:
The JKS keystore uses a proprietary format. It is recommended to migrate to PKCS12 which is an industry standard format using "keytool -importkeystore -srckeystore x.keystore -destkeystore x.keystore -deststoretype pkcs12".
keytool -list -keystore b.keystore
Enter keystore password:

Keystore type: JCEKS
Keystore provider: SunJCE

Your keystore contains 1 entry

foo, Oct 15, 2019, PrivateKeyEntry,
Certificate fingerprint (SHA-256): B2:61:07:4D:D5:12:58:D7:F8:49:BB:1A:7E:69:FC:F2:C4:3E:3A:9B:F3:B0:E0:F0:F5:3E:9F:46:C4:8B:A7:86

Warning:
The JCEKS keystore uses a proprietary format. It is recommended to migrate to PKCS12 which is an industry standard format using "keytool -importkeystore -srckeystore y.keystore -destkeystore y.keystore -deststoretype pkcs12".
keytool -list -keystore c.keystore
Enter keystore password:
Keystore type: PKCS12
Keystore provider: SUN

Your keystore contains 1 entry

foo, Oct 15, 2019, PrivateKeyEntry,
Certificate fingerprint (SHA-256): B4:E3:38:34:21:27:AC:0F:43:09:46:BC:FE:41:DF:1E:F5:5F:3A:75:75:52:D3:7C:42:A4:F7:57:B5:FC:34:9E

Note that the fingerprints are different and the store types JKS and JCEKS generate a warning.
The keystore provider for PKCS12 is SunJSSE in Java 7 and SUN in Java 10.


On UNIX systems you can use the file command to get an indication of the resp. store type.
file *.keystore

a.keystore: Java KeyStore
b.keystore: Java JCE KeyStore
c.keystore: data
i.e. the file "magic" can identify the old JKS and JCEKS keystores but the newest recommended PKCS12 is only shown as data.