Client receives ‘Failed to load SSL keystore’ message when communicating with brokers

Symptoms

When executing operations with a Java client connected to Event Streams, the client fails with an error similar to the following:

org.apache.kafka.common.KafkaException: Failed to load SSL keystore /path/to/es-cert.p12 of type PKCS12
  at org.apache.kafka.common.security.ssl.DefaultSslEngineFactory$FileBasedStore.load(DefaultSslEngineFactory.java:377)
  at org.apache.kafka.common.security.ssl.DefaultSslEngineFactory$FileBasedStore.<init>(DefaultSslEngineFactory.java:349)
  at org.apache.kafka.common.security.ssl.DefaultSslEngineFactory.createkeystore(DefaultSslEngineFactory.java:322)
  at org.apache.kafka.common.security.ssl.DefaultSslEngineFactory.configure(DefaultSslEngineFactory.java:168)
  ...
Caused by: java.io.IOException: Error extracting keyentry aliases from PFX
  at com.ibm.crypto.provider.PKCS12KeyStoreOracle.engineLoad(Unknown Source)
  at java.security.KeyStore.load(KeyStore.java:1456)

or:

Caused by: java.io.IOException: parseAlgParameters failed: ObjectIdentifier() -- data isn't an object ID (tag = 48)
  at sun.security.pkcs12.PKCS12KeyStore.parseAlgParameters(PKCS12KeyStore.java:829)
  at sun.security.pkcs12.PKCS12KeyStore.engineLoad(PKCS12KeyStore.java:2037)
  at java.security.KeyStore.load(KeyStore.java:1445)

This is seen in various Java-based clients including the Kafka connectors included in IBM App Connect Enterprise Version 12.0.

Causes

The PKCS12-format keystore file that is generated in an Event Streams instance cannot be parsed by previous versions of Java. In Event Streams version 10.4.0 and later, the PKCS12-format keystore is generated by using a version of Java that includes an upgrade to the default algorithms used in PKCS12 to use new encryption and stronger algorithms.

Previous releases of Java do not include the upgrade and cannot successfully parse the PKCS12-format keystore from Event Streams.

Resolving the problem

To resolve the issue, you can update the version of Java that is running the Kafka client. Alternatively, you can work around the issue by converting the PCKS12-format keystore to a JKS-format keystore.

The upgrade to the default algorithms used in PKCS12 was back-ported to various Java releases. To determine which version of your Java release includes the upgrade, see the ‘Backports’ section in the associated OpenJDK issue.

To work around the issue you can convert the PCKS12-format keystore to a JKS-format keystore by using a tool such as keytool, and then provide that to the Java client instead. The following command will create a JKS-format keystore containing the certificates in the PKCS12-format keystore:

keytool -importkeystore \
 -srckeystore es-cert.p12 \
 -srcstoretype PKCS12 \
 -srcstorepass <CERTIFICATE PASSWORD> \
 -destkeystore es-cert.jks \
 -deststoretype jks \
 -deststorepass <CERTIFICATE PASSWORD>

The Java client properties will then need to be updated to point to the new file and set the truststore type, for example:

ssl.truststore.location=/path/to/es-cert.jks
ssl.truststore.password=<CERTIFICATE PASSWORD>
ssl.truststore.type=JKS