keytool Command Examples in Linux: Complete Cheat Sheet

keytool is the Java CLI for keystores and truststores: generate key pairs, build CSRs, import CA-signed certificates and PKCS12 bundles, list aliases, export PEM certs, and manage passwords. This cheat sheet covers everyday commands on Linux with PKCS12 examples tested on Ubuntu.

Published

Updated

Read time 15 min read

Reviewed byDeepak Prasad

keytool Command Examples in Linux: Complete Cheat Sheet
About keytool is the Java CLI for keystores and truststores: generate key pairs, build CSRs, import CA-signed certificates and PKCS12 bundles, list aliases, export PEM certs, and manage passwords. This cheat sheet covers everyday commands on Linux with PKCS12 examples tested on Ubuntu.
Tested on Ubuntu 25.04 (Plucky Puffin); OpenJDK 21.0.9; keytool 21.0.9; kernel 6.14.0-37-generic
Package default-jdk (apt/deb) · java-21-openjdk-devel (dnf/rpm)
Man page keytool(1)
Privilege user (own keystore files); sudo for system `cacerts` only
Distros

Linux, macOS, and Windows with a JDK installed (OpenJDK or Oracle).

PEM/private-key workflows and live TLS inspection: OpenSSL cheat sheet.

Related guide

keytool — quick reference

Key pairs and local certificates

Create the private key and an initial certificate inside a keystore — the usual first step before a CA signs your CSR.

When to use Command
Generate an RSA key pair and self-signed cert in a new PKCS12 keystore keytool -genkeypair -alias NAME -keyalg RSA -keysize 2048 -validity 365 -storetype PKCS12 -keystore store.p12 -storepass PASS -dname "CN=host" -noprompt
Add a Subject Alternative Name at creation time keytool -genkeypair … -ext "SAN=dns:localhost,ip:127.0.0.1"
Use an EC key instead of RSA keytool -genkeypair -alias NAME -keyalg EC -groupname secp256r1 -keystore store.p12 -storepass PASS -dname "CN=host" -noprompt
Set a separate key password (JKS; PKCS12 uses one store password) keytool -genkeypair … -keypass KEYPASS

Certificate requests and CA signing

Build a CSR from an existing key entry, then replace the self-signed cert with a CA reply.

When to use Command
Generate a CSR for an existing alias keytool -certreq -alias NAME -file host.csr -keystore store.p12 -storepass PASS
Add SAN extensions on the CSR keytool -certreq -alias NAME -file host.csr -keystore store.p12 -storepass PASS -ext "SAN=dns:app.example.com,ip:10.0.0.5"
Sign a CSR with a CA key already in the same keystore keytool -gencert -alias CA_ALIAS -infile host.csr -outfile host.crt -rfc
Show CSR contents without importing keytool -printcertreq -file host.csr

Import certificates and keystores

Bring external certs or whole keystores into Java stores.

When to use Command
Import a CA or server certificate file keytool -importcert -alias NAME -file cert.pem -keystore store.p12 -storepass PASS -noprompt
Install a CA-signed reply over the CSR alias (replaces chain) keytool -importcert -alias NAME -file signed.crt -keystore store.p12 -storepass PASS -noprompt
Trust CA certs from the JDK cacerts while building a chain keytool -importcert -alias NAME -file reply.crt -keystore store.p12 -storepass PASS -trustcacerts -noprompt
Copy one entry from another keystore keytool -importkeystore -srckeystore src.p12 -srcstoretype PKCS12 -srcstorepass PASS -destkeystore dest.p12 -deststoretype PKCS12 -deststorepass PASS -srcalias SRC -destalias DST -noprompt
Merge all entries from a source keystore keytool -importkeystore -srckeystore src.p12 -srcstorepass PASS -destkeystore dest.p12 -deststorepass PASS -noprompt
Import a public CA into the system truststore (needs sudo) sudo keytool -importcert -alias NAME -file ca.crt -cacerts -storepass changeit -noprompt

Export, list, and inspect

Read what is inside a keystore or a standalone certificate file.

When to use Command
List all aliases (summary) keytool -list -keystore store.p12 -storepass PASS
List one alias with full cert details (expiry, SAN, fingerprints) keytool -list -v -alias NAME -keystore store.p12 -storepass PASS
List the JDK default truststore keytool -list -cacerts -storepass changeit
Export a certificate as binary DER keytool -exportcert -alias NAME -file cert.der -keystore store.p12 -storepass PASS
Export a certificate as PEM (-rfc) keytool -exportcert -alias NAME -rfc -file cert.pem -keystore store.p12 -storepass PASS
Print any PEM or DER certificate file keytool -printcert -file cert.pem
Print a CRL file keytool -printcrl -file ca.crl

Keystore management

Rename entries, rotate passwords, or remove bad aliases.

When to use Command
Rename an alias keytool -changealias -alias OLD -destalias NEW -keystore store.p12 -storepass PASS -noprompt
Change the keystore file password keytool -storepasswd -keystore store.p12 -storepass OLD -new NEW
Change an entry key password (JKS only — not PKCS12) keytool -keypasswd -alias NAME -keystore store.jks -storepass STOREPASS -keypass OLD -new NEW
Delete an alias keytool -delete -alias NAME -keystore store.p12 -storepass PASS -noprompt

Version and help

When to use Command
Show all commands keytool -help
Help for one command keytool -importcert --help
Print keytool and JDK tool version keytool -version

keytool — command syntax

keytool is mode-based: the first argument after keytool selects the operation (-genkeypair, -list, …). Synopsis from keytool -help on Ubuntu 25.04 (OpenJDK 21.0.9):

text
keytool -certreq            Generates a certificate request
keytool -changealias        Changes an entry's alias
keytool -delete             Deletes an entry
keytool -exportcert         Exports certificate
keytool -genkeypair         Generates a key pair
keytool -genseckey          Generates a secret key
keytool -gencert            Generates certificate from a certificate request
keytool -importcert         Imports a certificate or a certificate chain
keytool -importpass         Imports a password
keytool -importkeystore     Imports one or all entries from another keystore
keytool -keypasswd          Changes the key password of an entry
keytool -list               Lists entries in a keystore
keytool -printcert          Prints the content of a certificate
keytool -printcertreq       Prints the content of a certificate request
keytool -printcrl           Prints the content of a CRL file
keytool -storepasswd        Changes the store password of a keystore
keytool -showinfo           Displays security-related information
keytool -version            Prints the program version

Each mode accepts its own flags — run keytool -COMMAND --help for the full option list. PKCS12 (.p12) is the default keystore type on OpenJDK 9+; Tomcat and Spring Boot commonly use it. Install the CLI with Install keytool on Ubuntu if keytool: command not found.


keytool — command examples

The examples below use one lab keystore (lab.p12, password changeit) under /tmp/keytool-lab. Every command was run on Ubuntu 25.04 with OpenJDK 21.0.9.

Essential Generate a PKCS12 keystore and list entries

Start a new server identity: create an RSA key pair, self-signed certificate, and PKCS12 file in one step — then confirm the alias is a PrivateKeyEntry.

Prepare a clean lab directory:

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

Generate the keystore:

bash
keytool -genkeypair -alias server -keyalg RSA -keysize 2048 -validity 365 \
  -storetype PKCS12 -keystore lab.p12 -storepass changeit \
  -dname "CN=localhost, OU=Lab, O=GoLinuxCloud, L=City, ST=State, C=US" -noprompt

Sample output:

text
Generating 2,048 bit RSA key pair and self-signed certificate (SHA384withRSA) with a validity of 365 days
	for: CN=localhost, OU=Lab, O=GoLinuxCloud, L=City, ST=State, C=US

List what was created:

bash
keytool -list -keystore lab.p12 -storepass changeit

Sample output:

text
Keystore type: PKCS12
Keystore provider: SUN

Your keystore contains 1 entry

server, Jul 2, 2026, PrivateKeyEntry, 
Certificate fingerprint (SHA-256): B3:4A:F0:87:14:B7:E6:8F:90:07:91:30:B1:62:58:32:5C:7B:E7:7B:95:15:95:40:C3:C3:DF:14:EB:EA:C4:58

PrivateKeyEntry means the alias holds both the private key and certificate — what Tomcat and Spring Boot need for HTTPS.

Essential Create a CSR, sign with OpenSSL, import the CA chain

Replace the self-signed cert with a CA-signed chain: export a CSR from keytool, sign it with a local CA (OpenSSL here), import the CA cert, then import the signed reply on the same alias.

Create the CSR with SAN entries:

bash
keytool -certreq -alias server -file server.csr -keystore lab.p12 -storepass changeit \
  -ext "SAN=dns:localhost,ip:127.0.0.1"

Inspect the CSR:

bash
keytool -printcertreq -file server.csr | head -15

Sample output:

text
PKCS #10 Certificate Request (Version 1.0)
Subject: CN=localhost, OU=Lab, O=GoLinuxCloud, L=City, ST=State, C=US
...
SubjectAlternativeName [
  DNSName: localhost
  IPAddress: 127.0.0.1
]

Sign with a throwaway CA (OpenSSL — same pattern as a real internal CA):

bash
openssl req -x509 -newkey rsa:2048 -nodes -keyout ca.key -out ca.crt -days 365 \
  -subj "/CN=Lab CA" -addext "basicConstraints=critical,CA:TRUE"
openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial \
  -out server-signed.crt -days 365 -copy_extensions copyall

Import the CA, then install the signed reply on alias server:

bash
keytool -importcert -alias labca -file ca.crt -keystore lab.p12 -storepass changeit -noprompt
keytool -importcert -alias server -file server-signed.crt -keystore lab.p12 -storepass changeit -noprompt

Sample output:

text
Certificate was added to keystore
Certificate reply was installed in keystore

Verify the chain length:

bash
keytool -list -v -keystore lab.p12 -storepass changeit -alias server | head -12

Sample output:

text
Alias name: server
Creation date: Jul 2, 2026
Entry type: PrivateKeyEntry
Certificate chain length: 2
Certificate[1]:
Owner: CN=localhost, OU=Lab, O=GoLinuxCloud, L=City, ST=State, C=US
Issuer: CN=Lab CA

Chain length 2 means leaf plus issuing CA — browsers and Java TLS need the intermediate/issuer present, not only the leaf file.

Essential Inspect expiry, issuer, and SHA-256 fingerprint

Before you trust or deploy a cert, list one alias verbosely — this is the usual “what expires when?” check on an unknown keystore.

bash
keytool -list -v -alias server -keystore lab.p12 -storepass changeit

Sample output (trimmed):

text
Alias name: server
Entry type: PrivateKeyEntry
Certificate chain length: 2
Certificate[1]:
Owner: CN=localhost, OU=Lab, O=GoLinuxCloud, L=City, ST=State, C=US
Issuer: CN=Lab CA
Valid from: Thu Jul 02 15:10:54 IST 2026 until: Fri Jul 02 15:10:54 IST 2027
Certificate fingerprints:
	 SHA256: 31:F6:FA:94:FE:39:0C:99:B5:11:4B:8B:BE:E3:64:B5:C2:F8:64:5F:7C:05:74:D3:27:2C:66:95:35:6E:B5:7D

Compare that SHA-256 line with keytool -printcert -file or openssl x509 -noout -fingerprint -sha256 before you import a file someone emailed you.

Common Export a certificate to PEM and print it

Share the public certificate without exporting the private key — PEM (-rfc) is what nginx and many tools expect.

Export DER and PEM:

bash
keytool -exportcert -alias server -file server.der -keystore lab.p12 -storepass changeit
keytool -exportcert -alias server -rfc -file server.pem -keystore lab.p12 -storepass changeit

Sample output:

text
Certificate stored in file <server.der>
Certificate stored in file <server.pem>

Print the PEM file:

bash
keytool -printcert -file server.pem | head -10

Sample output:

text
Owner: CN=localhost, OU=Lab, O=GoLinuxCloud, L=City, ST=State, C=US
Issuer: CN=Lab CA
Serial number: 72b4a19cb1069e9c400708fa5890a5442e1e40b6
Valid from: Thu Jul 02 15:10:54 IST 2026 until: Fri Jul 02 15:10:54 IST 2027
Certificate fingerprints:
	 SHA256: 31:F6:FA:94:FE:39:0C:99:B5:11:4B:8B:BE:E3:64:B5:C2:F8:64:5F:7C:05:74:D3:27:2C:66:95:35:6E:B5:7D

-exportcert on a PrivateKeyEntry exports only the public certificate — never the private key.

Common Rename an alias without regenerating keys

Tomcat server.xml and Spring Boot server.ssl.key-alias must match the keystore alias — rename instead of reissuing when only the name was wrong.

Before:

bash
keytool -list -keystore lab.p12 -storepass changeit

Rename server to app-server:

bash
keytool -changealias -alias server -destalias app-server -keystore lab.p12 -storepass changeit -noprompt

After:

bash
keytool -list -keystore lab.p12 -storepass changeit

Sample output:

text
Your keystore contains 2 entries

app-server, Jul 2, 2026, PrivateKeyEntry, 
Certificate fingerprint (SHA-256): 31:F6:FA:94:FE:39:0C:99:B5:11:4B:8B:BE:E3:64:B5:C2:F8:64:5F:7C:05:74:D3:27:2C:66:95:35:6E:B5:7D
labca, Jul 2, 2026, trustedCertEntry, 
Certificate fingerprint (SHA-256): 58:48:86:5E:C3:85:A3:BF:FF:41:0D:C3:2B:DE:89:BB:BE:D4:F5:0D:22:7B:EB:61:A7:E0:C9:14:17:91:80:9B

The private key and chain stay attached — only the alias string changes.

Common Rotate the keystore password

Update the password on a PKCS12 file before you hand it to another team or paste it into a secrets manager.

bash
keytool -storepasswd -keystore lab.p12 -storepass changeit -new newstore
keytool -list -keystore lab.p12 -storepass newstore | head -5
keytool -storepasswd -keystore lab.p12 -storepass newstore -new changeit

Sample output:

text
Keystore type: PKCS12
Keystore provider: SUN

Your keystore contains 2 entries

Use -new PASSWORD immediately after -storepass — there is no -newstorepass flag. On PKCS12, the store password protects the whole file; -keypasswd is not supported (see Troubleshooting).

Common Import one alias from another keystore, then delete it

Merge a .p12 from another system, then remove a stale alias — typical when consolidating keystores after a migration.

Create a second keystore and import one alias into lab.p12:

bash
keytool -genkeypair -alias other -keyalg RSA -keysize 2048 -validity 30 \
  -storetype PKCS12 -keystore other.p12 -storepass changeit -dname "CN=other" -noprompt
keytool -importkeystore -srckeystore other.p12 -srcstoretype PKCS12 -srcstorepass changeit \
  -destkeystore lab.p12 -deststoretype PKCS12 -deststorepass changeit \
  -srcalias other -destalias imported-other -noprompt

Sample output:

text
Importing keystore other.p12 to lab.p12...

List three entries, then delete the import:

bash
keytool -list -keystore lab.p12 -storepass changeit
keytool -delete -alias imported-other -keystore lab.p12 -storepass changeit -noprompt
keytool -list -keystore lab.p12 -storepass changeit

Sample output after delete:

text
Your keystore contains 2 entries

app-server, Jul 2, 2026, PrivateKeyEntry, 
labca, Jul 2, 2026, trustedCertEntry,

Omit -srcalias / -destalias to copy every entry from the source keystore.

Advanced List the JDK default truststore (cacerts)

Java HTTPS clients trust CAs bundled in cacerts unless you point at a custom truststore. List it read-only before you add a private CA.

bash
keytool -list -cacerts -storepass changeit | head -8

Sample output:

text
Keystore type: JKS
Keystore provider: SUN

Your keystore contains 113 entries

debian:ac_raiz_fnmt-rcm.pem, Jul 2, 2026, trustedCertEntry,

Default password is changeit. Import a private CA with sudo keytool -importcert -alias myca -file ca.crt -cacerts -storepass changeit -noprompt only when you intend to trust that CA JVM-wide — prefer a custom truststore for application-specific CAs.


keytool — when to use / when not

Use keytool when Use something else when
  • You manage a Java keystore (PKCS12, JKS) for Tomcat, Spring Boot, Kafka, or JDBC TLS
  • You need to import a CA-signed reply onto an existing CSR alias
  • You inspect aliases, expiry, or fingerprints inside a .p12 / .jks file
  • You add a CA to cacerts or a custom Java truststore
  • You create PEM keys, CSRs, or inspect a live HTTPS cert → OpenSSL
  • You only need keytool installed → Install keytool on Ubuntu
  • You convert PEM private key + cert to PKCS12 → OpenSSL PKCS12, then optional -importkeystore
  • You configure nginx/apache PEM paths directly → OpenSSL export, not Java keystore

keytool vs OpenSSL

Task keytool OpenSSL
Generate RSA/EC key + self-signed cert in a Java keystore Yes (-genkeypair) Yes (req -x509) — PEM files
Create CSR Yes (-certreq) Yes (req -new)
Sign CSR with a CA Yes (-gencert if CA key is in keystore) Yes (x509 -req) — typical for local CAs
Inspect remote HTTPS certificate No Yes (s_client)
Merge key + cert into PKCS12 for Java Yes (-genkeypair or -importkeystore) Yes (pkcs12 -export) — common interop path
Manage Java cacerts truststore Yes (-importcert -cacerts) No

Use both: OpenSSL for PKI creation and PEM operations; keytool for Java-native stores and cacerts. See OpenSSL cheat sheet for the other half of the workflow.


Java TLS and keystore work often sits beside OpenSSL PKI tools and the JDK install itself.

Command One line
keytool Java keystore and truststore management
openssl PEM keys, CSRs, chains, PKCS12, live TLS checks
java JVM runtime — install via default-jdk to get keytool
keytool install guide Fix command not found, JAVA_HOME, and apt packages

More command decks: Linux commands cheat sheet.


keytool — interview corner

What is the difference between a keystore and a truststore in Java?

A keystore usually holds your identity: private key plus certificate chain (Tomcat HTTPS, mutual TLS client cert). A truststore holds trusted public CAs — certificates you accept when validating peers.

keytool uses the same file format for both; the difference is entry type and how the app configures it:

Store role Typical entries Java config
Keystore PrivateKeyEntry javax.net.ssl.keyStore
Truststore trustedCertEntry javax.net.ssl.trustStore

List entry types:

bash
keytool -list -v -keystore server.p12 -storepass changeit

Sample line:

text
app-server, Jul 2, 2026, PrivateKeyEntry,

Versus a CA-only import:

text
labca, Jul 2, 2026, trustedCertEntry,

A strong answer is:

A keystore is for my keys and certs; a truststore is for CAs I trust. Same tool and file types, but PrivateKeyEntry means identity, trustedCertEntry means anchor only — apps point keyStore and trustStore at different files or aliases.

Why is PKCS12 preferred over JKS today?

JKS was Java’s legacy proprietary format. PKCS12 (.p12) is an open standard interoperable with OpenSSL, Windows, and modern Java.

Since Java 9 (JEP 229), PKCS12 is the default storetype when you omit -storetype:

bash
keytool -genkeypair -alias demo -keyalg RSA -keysize 2048 -validity 30 \
  -keystore demo.p12 -storepass changeit -dname "CN=demo" -noprompt
keytool -list -keystore demo.p12 -storepass changeit | head -3

Sample output:

text
Keystore type: PKCS12

Legacy apps that require JKS: -storetype JKS on generate/import, or -importkeystore to convert.

A strong answer is:

PKCS12 is standard, interoperable, and the OpenJDK default since Java 9. I use JKS only when a legacy app demands it; otherwise PKCS12 for Tomcat, Spring Boot, and OpenSSL hand-off.

What happens when you import a CA-signed certificate with -importcert?

If the alias already has a PrivateKeyEntry from -genkeypair and the signed cert matches the CSR, keytool replaces the self-signed cert with the CA reply and builds the chain:

text
Certificate reply was installed in keystore

If the public key does not match, you get:

text
keytool error: java.lang.Exception: Public keys in reply and keystore don't match

That usually means wrong alias, wrong CSR, or importing someone else’s certificate.

A strong answer is:

importcert on a CSR alias installs the signed reply over the existing private key. The reply must match the key that generated the CSR — alias mix-ups cause the public keys don't match error.

What is the difference between PrivateKeyEntry and trustedCertEntry?
Entry type Contains Typical use
PrivateKeyEntry Private key + cert chain Server HTTPS, client mTLS identity
trustedCertEntry Public certificate only Imported CA or peer cert you trust

Importing only a .crt file without a private key creates trustedCertEntry — a common mistake when you meant to load a TLS identity.

A strong answer is:

PrivateKeyEntry means key plus certs — that's your TLS identity. trustedCertEntry is trust-only, no private key — CA imports and peer anchors.

What is the default cacerts password and where is the file?

The default password is changeit. Path depends on JAVA_HOME:

bash
KEYTOOL=$(readlink -f "$(command -v keytool)")
JAVA_HOME=$(dirname "$(dirname "$KEYTOOL")")
ls -l "$JAVA_HOME/lib/security/cacerts"

List without modifying:

bash
keytool -list -cacerts -storepass changeit | head -5

A strong answer is:

cacerts lives under JAVA_HOME/lib/security, default password changeit. I list with -cacerts before importing private CAs, and prefer a custom truststore over editing global cacerts in production.

What causes Failed to establish chain from reply in keytool?

The signed reply cannot link to a trusted issuer already in the keystore (or cacerts with -trustcacerts). Typical causes:

  • Intermediate CA cert not imported before the leaf reply
  • Wrong order: leaf imported as new alias instead of reply on CSR alias
  • Missing root CA in the store

Fix: import root and intermediate CAs as trustedCertEntry aliases first, then import the server reply on the key alias with -trustcacerts if needed.

A strong answer is:

Chain failure means keytool cannot path-build from the reply to a trust anchor in the keystore. I import intermediate and root CAs first, then install the reply on the original CSR alias.


Troubleshooting

Symptom Likely cause Fix
keytool: command not found JDK not installed or not on PATH Install keytool on Ubuntu
Failed to establish chain from reply Missing intermediate/root CA in keystore Import CA certs first; retry with -trustcacerts
Public keys in reply and keystore don't match Signed cert does not match CSR alias / key Import reply on the same alias that generated the CSR
keypasswd … not supported if -storetype is PKCS12 PKCS12 uses one password for store and key Change only -storepasswd; use JKS if you truly need separate key passwords
Illegal option: -newstorepass Wrong flag name Use -new PASSWORD with -storepasswd and -keypasswd
trustedCertEntry but you expected HTTPS identity Imported .crt only — no private key Import PKCS12 from OpenSSL or regenerate with -genkeypair
Hostname verification fails in Java client Cert lacks SAN Regenerate CSR with -ext "SAN=dns:host,..."
Wrong cacerts edited Multiple JDKs installed readlink -f $(which keytool) and use that JAVA_HOME

References

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 …