Here are some great answers, but I have figured out, in some cases some p12 certificates may not work under some circumstances if converted to jks. For example we had the jks, generated in keytool from Java 11, which were OK for the application running in tomcat 9 on Java 11, but certificate created in the same way then did not work in Tomcat 10 with java 17 in the case the application runs in the compatibility mode with the old javax libraries, so there is not clear, which libraries are in the reality how used for the access of the jks keystore from Java application.
We then got the "Invalid keystore format" exceptions for such keystores on such infrastructure.
Also is important with which Java version the keytool is keystore is generated.
But I got the information, if the PKCS12 keystore is once "prepared to be fully java-compatible" - please do not ask me, what does it mean :-) - then it works - it seems not all p12 certificates are the same. And really, this also was our case - so in the case you need to store in jks the client certificate originally delivered in p12 format to access some remote service as the client, then you might find this script handsome - it first reconverts the p12 certificate through pem and then creates the jks keystore and then also renames the imported key in the keystore to be named with the alias which is requested.
#!/bin/bash
############### start of the execution ################
#Perform initial cleanup:
echo -e 'Cleanup of possibly existing temporary files...'
rm -f "${PKCS12_FILENAME}.pem"
#First delete also the result keystore if existing - there can be only one client certificate in client keystore, so any previous keystore content will be so deleted:
rm -f "${KEYSTORE_FILENAME}"
rm -f "JAVA_FULLY_COMPATIBLE_${KEYSTORE_FILENAME}"
echo -e 'Starting...'
#For export of the p12 certificate into pem format use following statement:
openssl pkcs12 -in "${PKCS12_FILENAME}" -out "${PKCS12_FILENAME}.pem" -descert -passin pass:"${PKCS12_PASSWORD}" -passout pass:"${PKCS12_PASSWORD}"
# Create Java-fully-compatible P12 certificate file:
openssl pkcs12 -export -out "JAVA_FULLY_COMPATIBLE_${PKCS12_FILENAME}" -in "${PKCS12_FILENAME}.pem" -passin pass:"${PKCS12_PASSWORD}" -passout pass:"${PKCS12_PASSWORD}"
#Now create the JKS keystore from the fully compatible PKCS12 certificate
${KEYTOOL_LOCATION}keytool -importkeystore -srckeystore "JAVA_FULLY_COMPATIBLE_${PKCS12_FILENAME}" -srcstoretype PKCS12 -srcstorepass "${PKCS12_PASSWORD}" -deststorepass "${KEYSTORE_PASSWORD}" -destkeypass "${PKCS12_PASSWORD}" -deststoretype ${KEYSTORE_TYPE} -destkeystore "${KEYSTORE_FILENAME}"
#Now rename the key in the keystore to the wished alias, the default created key is named "1"
${KEYTOOL_LOCATION}keytool -changealias -alias "1" -destalias "${ALIAS}" -keypass "${PKCS12_PASSWORD}" -keystore "${KEYSTORE_FILENAME}" -storepass "${KEYSTORE_PASSWORD}"
echo -e 'Keystore with following content created:'
${KEYTOOL_LOCATION}keytool -list -keystore "${KEYSTORE_FILENAME}" -storepass "${KEYSTORE_PASSWORD}"
echo -e 'Finished.'
It is called for example like this (the above script is in file keystore-gen-tomcat-compatibility-mode.sh
):
#!/bin/bash
# Created with the help of following sources:
# https://mcmap.net/q/406000/-need-help-converting-p12-certificate-into-jks
# Customize following properties to meet your needs
KEYTOOL_LOCATION="/usr/lib/jdk11.0/bin/"
PKCS12_FILENAME="my p12 certificate.p12"
PKCS12_PASSWORD="pkcspwd"
# possible values here are {jks|pkcs12}:
KEYSTORE_TYPE=jks
KEYSTORE_FILENAME="java_keystore.jks"
KEYSTORE_PASSWORD="jkspwd"
ALIAS=${PKCS12_FILENAME}
#performs the generation based on corresponding variables:
. ../../../common/certs/keystore-gen-tomcat-compatibility-mode.sh
Exception in thread "main" java.lang.AssertionError: Platform not recognized at sun.nio.fs.DefaultFileSystemProvider.create(DefaultFileSystemProvider.java:85) at java.io.FilePermission.<clinit>(FilePermission.java:191) at sun.net.www.protocol.file.FileURLConnection.getPermission(FileURLConnection.java:225) at java.net.URLClassLoader.getPermissions(URLClassLoader.java:666) at java.security.SecureClassLoader.getProtectionDomain(SecureClassLoader.java:206)
though it works fine on mac terminal. Any lead on how to fix this? – Tutelary