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:
openssl
.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.)
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 ""