Convert JKS to PKCS12 and PKCS12 to JKS with keytool

Convert Java JKS keystores to PKCS12 and PKCS12 back to JKS with keytool -importkeystore, understand the proprietary JKS warning, and learn why OpenJDK defaults to PKCS12 since Java 9 (JEP 229).

Published

Updated

Read time 7 min read

Reviewed byDeepak Prasad

Convert JKS to PKCS12 keystore banner with format arrows and keytool command

Legacy Java deployments still use JKS (.jks) keystores, while modern stacks, OpenSSL, and cloud load balancers expect PKCS12 (.p12). keytool does not ship a convert subcommand — you use -importkeystore to copy every entry from one store type into another. The same command works in both directions.

This guide walks through PKCS12 → JKS and JKS → PKCS12 conversion on Ubuntu with OpenJDK 25, explains the proprietary-format warning, and ties the default store type to JEP 229.

Tested on: Ubuntu 26.04 LTS; OpenJDK 25.0.3; kernel 7.0.0-27-generic.


Prerequisites

  • keytool from OpenJDK 8+ (-importkeystore is available in all supported releases).
  • Source keystore file and password.
  • Backup of the original file before in-place conversion.

Install the CLI with Install keytool on Ubuntu if needed. For importing vendor PKCS12 files without conversion, see Import PKCS12/PFX into Java keystore.


JKS vs PKCS12 at a glance

Format Extension Standard OpenJDK default (9+) Interop
JKS .jks Sun proprietary No Java-centric, legacy
PKCS12 .p12, .pfx RFC 7292 Yes (JEP 229) OpenSSL, browsers, Java

Prefer PKCS12 for new work. Convert to JKS only when an old config hard-codes keystoreType="JKS" or a library rejects PKCS12.


Lab setup

Build a PKCS12 source, then import it into JKS so both formats exist for the conversion steps below. You will convert in both directions from these two files.

Generate cert material, export PKCS12, and create the JKS copy:

bash
mkdir -p /tmp/keytool-lab && cd /tmp/keytool-lab

openssl req -x509 -newkey rsa:2048 \
  -keyout server.key -out server.crt \
  -days 365 -nodes -subj "/CN=lab.example.com"

openssl pkcs12 -export \
  -inkey server.key -in server.crt \
  -out server.p12 -name pem-right \
  -passout pass:changeit

keytool -importkeystore \
  -srckeystore server.p12 -srcstoretype PKCS12 -srcstorepass changeit \
  -destkeystore from-pkcs12.jks -deststoretype JKS -deststorepass changeit \
  -noprompt

from-pkcs12.jks is the JKS copy; server.p12 remains the PKCS12 original.


Convert PKCS12 to JKS

Point -srcstoretype at PKCS12 and -deststoretype at JKS. Use this path only when legacy tooling insists on .jks.

Confirm the PKCS12 source before you convert — check store type, alias, entry type, and fingerprint:

bash
keytool -list -v -keystore server.p12 -storetype PKCS12 -storepass changeit
text
Keystore type: PKCS12
Alias name: pem-right
Entry type: PrivateKeyEntry
Certificate chain length: 1
Certificate fingerprints:
	 SHA256: 5F:04:D5:97:A7:FD:89:E4:8B:7C:EA:96:57:BE:4B:56:1A:CA:9C:CD:29:81:5F:D2:E0:BB:44:0E:E5:E7:EB:84

Copy server.p12 into a new JKS file legacy.jks:

bash
keytool -importkeystore \
  -srckeystore server.p12 -srcstoretype PKCS12 -srcstorepass changeit \
  -destkeystore legacy.jks -deststoretype JKS -deststorepass changeit \
  -noprompt

The success line confirms the private key and certificate moved; the JKS warning is informational:

text
Importing keystore server.p12 to legacy.jks...
Entry for alias pem-right successfully imported.
Import command completed:  1 entries successfully imported, 0 entries failed or cancelled

Warning:
The JKS keystore uses a proprietary format. It is recommended to migrate to PKCS12 which is an industry standard format using "keytool -importkeystore -srckeystore legacy.jks -destkeystore legacy.jks -deststoretype pkcs12".

List the destination keystore and confirm store type and entry type:

bash
keytool -list -v -keystore legacy.jks -storetype JKS -storepass changeit

The destination should report JKS and still show PrivateKeyEntry:

text
Keystore type: JKS
Alias name: pem-right
Entry type: PrivateKeyEntry
Certificate chain length: 1

Convert JKS to PKCS12

Reverse the store types — this is the migration path most teams need today. The destination file is standard PKCS12 with no proprietary-format warning.

List the JKS source first so you know the aliases, entry types, and fingerprint before migration:

bash
keytool -list -v -keystore from-pkcs12.jks -storetype JKS -storepass changeit
text
Keystore type: JKS
Alias name: pem-right
Entry type: PrivateKeyEntry
Certificate chain length: 1
Certificate fingerprints:
	 SHA256: 5F:04:D5:97:A7:FD:89:E4:8B:7C:EA:96:57:BE:4B:56:1A:CA:9C:CD:29:81:5F:D2:E0:BB:44:0E:E5:E7:EB:84

Import from the lab JKS file into converted.p12:

bash
keytool -importkeystore \
  -srckeystore from-pkcs12.jks -srcstoretype JKS -srcstorepass changeit \
  -destkeystore converted.p12 -deststoretype PKCS12 -deststorepass changeit \
  -noprompt

All entries copy when import reports zero failures:

text
Importing keystore from-pkcs12.jks to converted.p12...
Entry for alias pem-right successfully imported.
Import command completed:  1 entries successfully imported, 0 entries failed or cancelled
NOTE
If the JKS source uses a key password different from the store password, keytool may prompt for the source key password during import. For non-interactive migration, test the conversion in a terminal first, then document the required source store and key passwords before automating it.
NOTE
For PKCS12 destinations, standardize on one destination store password. Do not rely on separate per-key passwords after migration; that is a legacy JKS pattern. Per-key -keypasswd is JKS-only — see Change alias, password, delete.

List the PKCS12 output — no JKS warning on the destination:

bash
keytool -list -keystore converted.p12 -storetype PKCS12 -storepass changeit

Confirm Keystore type: PKCS12 and the same alias fingerprint as the source:

text
Keystore type: PKCS12
Keystore provider: SUN

Your keystore contains 1 entry

pem-right, Jul 2, 2026, PrivateKeyEntry,
Certificate fingerprint (SHA-256): 5F:04:D5:97:A7:FD:89:E4:8B:7C:EA:96:57:BE:4B:56:1A:CA:9C:CD:29:81:5F:D2:E0:BB:44:0E:E5:E7:EB:84

The SHA-256 fingerprint matches the JKS source — only the container format changed. Point your server config at the PKCS12 file:

properties
server.ssl.key-store=file:/etc/tls/converted.p12
server.ssl.key-store-password=changeit
server.ssl.key-store-type=PKCS12
server.ssl.key-alias=pem-right

Tomcat connector fragment:

xml
<Certificate
    certificateKeystoreFile="/etc/tls/converted.p12"
    certificateKeystorePassword="changeit"
    certificateKeystoreType="PKCS12"
    certificateKeyAlias="pem-right" />

For full Spring Boot and Tomcat HTTPS setup, see Spring Boot HTTPS with keytool and Tomcat SSL with keytool.


In-place JKS to PKCS12 (same filename)

To replace a .jks file without keeping two copies, use the same path for -srckeystore and -destkeystore. Back up first — keytool rewrites the file in place.

Copy the JKS file, then convert with identical source and destination paths:

bash
cp from-pkcs12.jks from-pkcs12.jks.bak

keytool -importkeystore \
  -srckeystore from-pkcs12.jks -srcstoretype JKS -srcstorepass changeit \
  -destkeystore from-pkcs12.jks -deststoretype PKCS12 -deststorepass changeit \
  -noprompt

keytool rewrites the file as PKCS12. Keep the .bak until the application starts cleanly with keystoreType="PKCS12".

PKCS12, pkcs12, JKS, and jks are accepted case-insensitively by keytool; this guide uses uppercase for readability.


Convert keystores with multiple aliases

-importkeystore copies all entries when you omit -srcalias. For large keystores, list source aliases first so you know what will land in the destination.

Inspect the JKS source before a bulk conversion:

bash
keytool -list -keystore from-pkcs12.jks -storetype JKS -storepass changeit

If the destination keystore already contains an alias with the same name, convert into a new empty file or use -srcalias with -destalias to control each entry. Avoid bulk importing into a production keystore until you have listed both source and destination aliases.

If only some aliases should move, repeat -importkeystore with -srcalias and -destalias per entry, or delete unwanted aliases from the destination afterward with keytool -delete.


JEP 229: why PKCS12 is the default

Before Java 9, keytool -genkeypair created JKS by default. JEP 229 switched the default to PKCS12 while keeping JKS readable for migration. That is why new keystores show Keystore type: PKCS12 without extra flags, and why touching JKS triggers the proprietary-format warning.

NOTE
Do not create new JKS files for greenfield projects. Convert existing JKS once, standardize on .p12, and drop keystoreType="JKS" from server configs when possible.

Troubleshooting

Symptom Likely cause Fix
0 entries successfully imported Wrong -srcstoretype Match PKCS12 vs JKS to the actual file
Destination alias already exists Destination keystore already has the same alias Convert into a new file, delete/rename the destination alias, or use -srcalias and -destalias
Password errors on source vs dest Different passwords required Set -srcstorepass and -deststorepass explicitly
Lost private key after convert Source was truststore only Source must contain PrivateKeyEntry; see keystore vs truststore
Tomcat fails after PKCS12 migrate Still configured for JKS Set keystoreType="PKCS12" and update file extension in config

References


Summary

Use keytool -importkeystore for both directions: set -srcstoretype and -deststoretype to JKS or PKCS12 as needed. PKCS12 → JKS succeeds with a proprietary-format warning; JKS → PKCS12 is the recommended migration. OpenJDK has defaulted to PKCS12 since Java 9 (JEP 229). After any conversion, run keytool -list -v and confirm PrivateKeyEntry on every identity alias.


Frequently Asked Questions

1. How do I convert JKS to PKCS12 with keytool?

Run keytool -importkeystore -srckeystore file.jks -srcstoretype JKS -srcstorepass PASS -destkeystore file.p12 -deststoretype PKCS12 -deststorepass PASS -noprompt. List the result and confirm Keystore type: PKCS12 and PrivateKeyEntry on your aliases.

2. How do I convert PKCS12 to JKS?

Use the same -importkeystore command with -srcstoretype PKCS12 and -deststoretype JKS. Expect a warning that JKS is proprietary. Only convert to JKS when a legacy library or config file requires it.

3. Why does keytool warn about proprietary JKS format?

JKS is a Sun-specific keystore format predating PKCS12. OpenJDK recommends PKCS12 (RFC 7292) for interoperability with OpenSSL, browsers, and modern Java. The warning appears whenever you create or touch a JKS file on current JDKs.

4. Can I convert in place without a second filename?

Yes for JKS to PKCS12: keytool -importkeystore -srckeystore store.jks -destkeystore store.jks -deststoretype pkcs12 -srcstorepass PASS -deststorepass PASS. The file is rewritten as PKCS12. Back up first.

5. What is the default keystore type on OpenJDK 9 and later?

PKCS12, per JEP 229. On OpenJDK 9 and later, keytool creates a PKCS12 keystore by default when -storetype is not specified. The filename extension does not decide the store type; verify with keytool -list. JEP 229 changed the default keystore type from JKS to PKCS12, while existing keystores remain unchanged.
Deepak Prasad

R&D Engineer

Founder of GoLinuxCloud with more than 15 years of expertise in Linux, Python, Go, Laravel, DevOps, Kubernetes, Git, Shell scripting, OpenShift, AWS, Networking, and Security. With extensive …