JKS Certificate Validation and Import Scripts
Preparation
Before executing any scripts, ensure the working directory contains the necessary decrypted artifacts.
chmod 600) and clean up the workspace after completion.Required files:
- Target Java KeyStore file (already decoded and extracted).
- Plain text file containing the JKS password.
- Source file containing one or multiple X.509 certificates in PEM format.
Formatting JKS Output for Human Readability
The default keytool -list -v output is unstructured and difficult to read. This script parses the verbose output and formats it into strict, readable blocks containing only the Alias, SHA-256 fingerprint, validity dates, and the Owner’s Distinguished Name.
JKS_FILE="truststore.jks"
PASS_FILE="pass.txt"
LC_ALL=C keytool -list -v -keystore "$JKS_FILE" -storepass "$(cat "$PASS_FILE")" | awk '
/^Alias name:/ {
if (alias) {
print "Alias : " alias
print "SHA256: " fp
print "Valid : " valid
print "Owner : " owner
print "------------------------------------------------------------"
}
sub(/^Alias name:[ \t]*/, "");
alias=$0; fp="N/A"; valid="N/A"; owner="N/A"
}
/^Owner:/ { $1=""; owner=substr($0,2) }
/^Valid from:/ { valid=$0 }
/SHA256:/ || /SHA-256\):/ { fp=$NF }
END {
if (alias) {
print "Alias : " alias
print "SHA256: " fp
print "Valid : " valid
print "Owner : " owner
print "------------------------------------------------------------"
}
}
'keytool output format, causing this script to return incomplete or N/A data.Generating JKS State Dump
To avoid redundant disk I/O and repeated JVM initialization, extract the current state of the target JKS into an environment variable. This variable will hold the SHA-256 fingerprints of all existing entries for subsequent validation.
JKS_FILE="truststore.jks"
PASS_FILE="pass.txt"
export JKS_DUMP=$(LC_ALL=C keytool -list -keystore "$JKS_FILE" -storepass "$(cat "$PASS_FILE")")keytool -list without the -v flag. It only extracts aliases, dates, and fingerprints. It is sufficient for cryptographic comparison but lacks full Subject/Issuer metadata.Validating PEM Certificates Against JKS Dump
This script parses the source PEM file, computes the SHA-256 fingerprint for each block using openssl, and compares it strictly against the $JKS_DUMP variable. This prevents duplicate imports and verifies the presence of required CA nodes.
PEM_FILE="chain.pem"
awk -F'\n' '
BEGIN { cmd = "openssl x509 -noout -subject -fingerprint -sha256" }
/-----BEGIN CERTIFICATE-----/ { cert = "" }
{ cert = cert $0 "\n" }
/-----END CERTIFICATE-----/ {
print cert | cmd
close(cmd)
}
' "$PEM_FILE" | while read -r line; do
if [[ "$line" == subject=** ]] || [[ "$line" == subject** ]]; then
SUB="${line#*=}"
elif [[ "$line" == SHA256* ]]; then
FP="${line#*=}"
if echo "$JKS_DUMP" | grep -q "$FP"; then
echo "[PRESENT] $SUB"
else
echo "[MISSING] $SUB"
fi
fi
donesubject= output format. The fingerprint evaluation remains mathematically accurate, but the displayed subject strings might break.Importing Certificate Chain into JKS
This generic script splits a multi-certificate PEM file into individual temporary files and imports them sequentially into the target JKS. It operates independently of the validation step. To avoid alias collision, it generates a unique alias name based on the certificate’s SHA-256 hash prefix.
JKS_FILE="truststore.jks"
PASS_FILE="pass.txt"
PEM_FILE="chain.pem"
# 1. Split the multi-block PEM file into individual temporary files
awk '/-----BEGIN CERTIFICATE-----/{c++} {print > ("temp_cert_" c ".pem")}' "$PEM_FILE"
# 2. Iterate and import each file into the JKS
for cert_file in temp_cert_*.pem; do
# Extract an 8-character prefix from the SHA-256 hash to ensure uniqueness
fp_prefix=$(openssl x509 -in "$cert_file" -noout -fingerprint -sha256 | awk -F'=' '{print $2}' | tr -d ':' | cut -c 1-8 | tr 'A-Z' 'a-z')
alias_name="ca_node_${fp_prefix}"
keytool -importcert -file "$cert_file" \
-keystore "$JKS_FILE" \
-alias "$alias_name" \
-storepass "$(cat "$PASS_FILE")" \
-trustcacerts -noprompt
done
# 3. Clean up temporary operational files
rm temp_cert_*.pem