Creating .p12 truststore with openssl

11,903

Solution 1

A possible explanation for this behaviour:

The standard PKCS#12 provider up to Java 7 did not allow trusted certificate entries at all. The JSSE Reference Guide says this:

Storing trusted certificates in a PKCS12 keystore is not supported. PKCS12 is mainly used to deliver private keys with the associated certificate chains. It does not have any notion of "trusted" certificates. In terms of interoperability, other PKCS12 vendors have the same restriction. Browsers such as Mozilla and Internet Explorer do not accept a PKCS12 file with only trusted certificates.

This has changed a bit in Java 8, which supports trusted certificates in PKCS#12 - if they are marked with a special attribute (OID 2.16.840.1.113894.746875.1.1):

openssl pkcs12 -in microsoft.p12 -info
MAC Iteration 1024
MAC verified OK
PKCS7 Encrypted data: pbeWithSHA1And40BitRC2-CBC, Iteration 1024
Certificate bag
Bag Attributes
    friendlyName: microsoft it ssl sha2 (baltimore cybertrust root)
    2.16.840.1.113894.746875.1.1: <Unsupported tag 6>

Source:

Solution 2

I haven't found the way to do it with openssl, though I've found the way to do it with keytool (a part of OpenJDK suite).

I needed to create a keystore which would contain the CA certificate with the 2.16.840.1.113894.746875.1.1: <Unsupported tag 6> attribute and an additional certificate and its key without this attribute. I'd like to share the solution with other people who will find this page by googling openssl "2.16.840.1.113894.746875.1.1" :-)

This command creates a PKCS12 with the CA certificate (assuming you already have a CA) which has 2.16.840.1.113894.746875.1.1: <Unsupported tag 6> attribute:

keytool -storepass '***' -import -alias ca -file ***/ca.crt.pem -keystore ***/ca.p12 -deststoretype PKCS12

This command converts the additional PEM-encoded certificate and its private key to PKCS12:

openssl pkcs12 -in ***/additional.cert.pem -inkey ***/additional.key.pem -name additional -export -out ***/additional.p12

This command merges the PKCS12 keystore containing the CA certificate to the PKCS12 keystore containing the additional and its private key:

keytool -importkeystore -srckeystore ***/ca.p12 -srcstoretype pkcs12 -srcstorepass '***' -destkeystore ***/additional.p12 -deststoretype pkcs12 -deststorepass '***'
Share:
11,903
Bragolgirith
Author by

Bragolgirith

Updated on July 19, 2022

Comments

  • Bragolgirith
    Bragolgirith almost 2 years

    I'm writing a Java 8 application and want to set up a simple keystore and truststore using a self-signed certificate.

    Normally this goes as follows:

    1. Create a keypair + certificate using openssl.
    2. Create a .jks keystore + .jks truststore using keytool

    Now I'd like to only use openssl and create .p12 keystores instead of .jks keystores.

    Creating a .p12 keystore works great using the following commands:

    # Create private key and certificate
    openssl req -x509 -newkey rsa:"${rsa}" -sha256 \
        -keyout "${key}" \
        -out "${cert}" \
        -days "${days}"
    
    # Create .p12 keystore
    openssl pkcs12 -export -in "${cert}" -inkey "${key}" -out "${keystore}"
    

    This keystore seems to be working correctly, as providing a corresponding .jks trustore in my Java application will get the TLS connection going. However I can't get a .p12 truststore working.

    I tried creating the truststore as suggested here:

    # Create .p12 truststore
    openssl pkcs12 -export -nokeys -in "${cert}" -out "${truststore}"
    

    and then loading it like this:

    FileInputStream fis = new FileInputStream(new File(trustorePath));
    KeyStore trustStore = KeyStore.getInstance("PKCS12");
    trustStore.load(fis, truststorePassword.toCharArray());
    fis.close();
    

    but I receive the following exception in my java code:

    Unexpected error: java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty

    Any ideas what I'm doing wrong?

    (A working snippet using .p12 truststore with Java 8 would be greatly appreciated.)

  • FUD
    FUD almost 6 years
    I am on "1.8.0_171" and this magic attribute is no longer required. All entries added to PKCS12 store are trusted when used in a trust manager.
  • dtheodor
    dtheodor almost 6 years
    I am on "1.8.0_171" and this is not working, PKCS12 containing only certificates give the "the trustAnchors parameter must be non-empty" error