PKCS #12 format works fine when used to provide ZooKeeper keystore, but additional steps are needed to use it for a dedicated truststore.
You will get the following error when you try to use PKCS #12 truststore.
2021-08-08 14:06:48,947 [myid:3] - WARN [QuorumConnectionThread-[myid=3]-86:QuorumCnxManager@397] - Cannot open secure channel to 2 at election address zookeeper2.example.org/172.16.0.112:3888 org.apache.zookeeper.common.X509Exception$SSLContextException: Failed to create TrustManager at org.apache.zookeeper.common.X509Util.createSSLContextAndOptionsFromConfig(X509Util.java:371) at org.apache.zookeeper.common.X509Util.createSSLContextAndOptions(X509Util.java:328) at org.apache.zookeeper.common.X509Util.createSSLContextAndOptions(X509Util.java:282) at org.apache.zookeeper.common.X509Util.getDefaultSSLContextAndOptions(X509Util.java:262) at org.apache.zookeeper.common.X509Util.createSSLSocket(X509Util.java:517) at org.apache.zookeeper.server.quorum.QuorumCnxManager.initiateConnection(QuorumCnxManager.java:379) at org.apache.zookeeper.server.quorum.QuorumCnxManager$QuorumConnectionReqThread.run(QuorumCnxManager.java:458) at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) at java.base/java.lang.Thread.run(Thread.java:829) Caused by: org.apache.zookeeper.common.X509Exception$TrustManagerException: java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty at org.apache.zookeeper.common.X509Util.createTrustManager(X509Util.java:512) at org.apache.zookeeper.common.X509Util.createSSLContextAndOptionsFromConfig(X509Util.java:369) ... 9 more Caused by: java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty at java.base/java.security.cert.PKIXParameters.setTrustAnchors(PKIXParameters.java:200) at java.base/java.security.cert.PKIXParameters.<init>(PKIXParameters.java:157) at java.base/java.security.cert.PKIXBuilderParameters.<init>(PKIXBuilderParameters.java:130) at org.apache.zookeeper.common.X509Util.createTrustManager(X509Util.java:489) ... 10 more
PKCS #12 truststore needs to contain a special attribute that cannot be added using OpenSSL utilities.
Export CA to the JKS format using keytool
utility.
$ keytool -noprompt -storepass "capassword" -keystore server.truststore.jks -alias CARoot -import -file ca.pem
Certificate was added to keystore
Export it to PKCS #12 format using keytool
utility. This the
$ keytool -importkeystore -srckeystore server.truststore.jks -destkeystore cacertificate.p12 -srcstoretype jks -deststoretype pkcs12 -srcstorepass capassword -deststorepass capassword
Importing keystore server.truststore.jks to cacertificate.p12... Entry for alias caroot successfully imported. Import command completed: 1 entries successfully imported, 0 entries failed or cancelled
Inspect the CA stored using PKCS #12 format, notice additional 2.16.840.1.113894.746875.1.1
OID.
$ openssl pkcs12 -in cacertificate.p12 -info -password pass:capassword
MAC: sha1, Iteration 100000 MAC length: 20, salt length: 20 PKCS7 Encrypted data: pbeWithSHA1And40BitRC2-CBC, Iteration 50000 Certificate bag Bag Attributes friendlyName: caroot 2.16.840.1.113894.746875.1.1: <Unsupported tag 6> subject=O = ZooKeeper, OU = Backend, emailAddress = admin@example.org issuer=O = ZooKeeper, OU = Backend, emailAddress = admin@example.org -----BEGIN CERTIFICATE----- MIIDcTCCAlmgAwIBAgIUda8Vsl8cbWcIWTgR9B1Uews99uUwDQYJKoZIhvcNAQEL BQAwSDESMBAGA1UECgwJWm9vS2VlcGVyMRAwDgYDVQQLDAdCYWNrZW5kMSAwHgYJ KoZIhvcNAQkBFhFhZG1pbkBleGFtcGxlLm9yZzAeFw0yMTA4MDgxOTE0MDlaFw0z MTA4MDYxOTE0MDlaMEgxEjAQBgNVBAoMCVpvb0tlZXBlcjEQMA4GA1UECwwHQmFj a2VuZDEgMB4GCSqGSIb3DQEJARYRYWRtaW5AZXhhbXBsZS5vcmcwggEiMA0GCSqG SIb3DQEBAQUAA4IBDwAwggEKAoIBAQC3CEu6v7tVlrnPAvUROHxw+Vikw/yIcCNu zjUDEIP/ulytHuFVzo5TwuVrEluTObOtethMc9FoXmeYa7oqDmSvSRF3I510/lpc qFmXgP+Ac0lnsWC3rlcwQuNxqkiE6DBNjNQYUmN1NyHW6WE1tjHXYKmcVq2ct2D2 fJu77qb0FIyHgdxaaX/1mapXw/spKrvduOgrjv/xXituT6kRo0vl1ww67w3/Sk3o wejhDS9K2jwyn1XTn29AWxTcAIQwerNVPnCh+G+Sf0FRk2IA5HIZ3KIxmTCscqLZ UEwRF/wQREiZQTwigW1CHCv8bklSAduZlOQWqVG9QFVUcZTco4MXAgMBAAGjUzBR MB0GA1UdDgQWBBToWI35o5pnWgk9DnI67h7/UXYeYzAfBgNVHSMEGDAWgBToWI35 o5pnWgk9DnI67h7/UXYeYzAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUA A4IBAQAeUYNhUWNsR4+sIc6Ep+7dd2goY6UWxK2yMFqUW1JjgmudKS75kXlskrxj 3+mgIV2tgTde/9IGoV1sLjfp+TiOE87HoEX//HzlepwzaURLAYiDA+3TSSa8S0Nz X2ceP+sksZhBPmb7KniDNclom4BnidUa7lCesHg2RTECxz5WCd0sFUcK4eRFzmf3 wLyHbvVPQx6O18H12V9ttHCkMRaW5JoEpbCsoKZEbpFIrlkKUaB3ndxmZEdaOOHm 4FF6iLnOyuRxJvfh6kYZfq62u1Cib2oaLXPHRH4/ZI8eolxbgC9dfTDKim8sjhpG ioVIt9vMSfI6/fD9e9F7Im4xx+Sj -----END CERTIFICATE-----
This is it. It will likely solve the same issue in different Java applications.