javasslopenssl

Creating .p12 truststore with openssl


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.)


Solution

  • 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: