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

  • This has beed fixed in OpenSSL 3.2+ (commit). Now you can create a p12 truststore directly with OpenSSL.

    A jdktrust option has been added. It has one option, anyExtendedKeyUsage.

    # Create a p12 truststore that can be directly used with java without a password.
    args=()
    args+=(-in "$pem_file")
    args+=(-out "$truststore_file")
    # Disable password. This is only certs--no key. No need for encryption.
    args+=(-keypbe NONE -certpbe NONE -nomaciter -passout pass:)
    # See
    # https://docs.openssl.org/3.2/man1/openssl-pkcs12/#pkcs12-output-export-options
    # for 'jdktrust' option.
    # https://github.com/openssl/openssl/commit/21f7a09ca256eee0ccc9a8fc498e8427469ab506
    # added the CLI option 'jdktrust' in openssl 3.2+ which does:
    # Export pkcs12 file in a format compatible with Java keystore
    # usage. This option accepts a string parameter indicating the
    # trust oid name to be granted to the certificate it is
    # associated with. Currently only "anyExtendedKeyUsage"
    # is defined. `-jdktrust` adds `-nokeys`.
    args+=(-jdktrust anyExtendedKeyUsage)
    
    openssl pkcs12 -export "${args[@]}"
    
    # Verify the truststore works with java.
    keytool -list -keystore "$truststore_file" -storepass ""