Jimmy Blue
Jimmy Blue

Reputation: 91

Java KeyStore-Handling of PKCS12

the project I'm currently working on involves the management of keystores and certificates. Therefor I use the Java Security API. The work with certificates works quit well, but the handling of PKCS12-KeyStores is a little bit confusing:

I exported a PKCS12-KeyStore from within windows certmgr which involved some public certificates (for test reasons certificates of CAs). The Security API opens the corresponding file without an error and reports there are no entries (to preclude personal programming errors, I will show the error by using the Java keytool which uses the same Security API).

#$ keytool -list -keystore keystore.pfx -storetype pkcs12 

Enter Keystore-Password:

Keystore-Type: PKCS12
Keystore-Provider: SunJSSE

Keystore contains 0 Entries

The KeyStore Explorer (different program) however shows all the entries.

If private Keys are added to the KeyStore, they are recognised by KeyTool.

Is there a general misunderstanding on my part or whats the case here?

Thanks in advance, Thomas

Upvotes: 3

Views: 5570

Answers (1)

GPI
GPI

Reputation: 9348

That's a limitation of the KeyStore API implementation in the standard Java/Sun security provider.

While dealing with a PKCS12 keystore, the standard implementation can not handle trusted certificate entries. Trying to write one such entry will result in an Unsupported Operation Exception, and reading one will produce no result.

It can, however, deal with Certificate entries that are linked to a Key entry.

(In this default implementation, the JKS format is better suited for a single KeyStore that is to handle both trusted entries and key entries in the same container). Other implementations of KeyStore (BouncyCastle) can provide better support for PKCS12.

See accepted answer at : Writing a client-server application that uses ssl / tls using java without beeing able to use keytool

For example : this will fail, throwing java.security.KeyStoreException: TrustedCertEntry not supported

KeyStore ks = KeyStore.getInstance("PKCS12");
ks.load(null, null);
ks.setCertificateEntry("test", certificate);

But this works:

Security.addProvider(new BouncyCastleProvider());
KeyStore ks = KeyStore.getInstance("PKCS12", BouncyCastleProvider.PROVIDER_NAME);
ks.load(null, null);
ks.setCertificateEntry("test", ca);

Upvotes: 6

Related Questions