rgoussu@goussu: ~/library/java/jdk-and-tools
~/library/java/jdk-and-tools cat keytool.md

keytool — keystores and certificates

# Manages PKCS12 keystores and truststores — keypairs, CSRs, CA imports, cacerts — and underpins most JVM TLS debugging.

Conceptsaved 2026-08-09 #java#tooling#security#tls#certificates

Overview

keytool manages the keystores the JVM's TLS stack (JSSE) reads: private keys with their certificate chains (a keystore, for the server/client identity) and trusted CA certificates (a truststore, for deciding who to believe). Since Java 9 the default format is standard PKCS12 rather than the proprietary JKS, so keytool artefacts interoperate with OpenSSL. Half of "Java can't connect over HTTPS" tickets end in a keytool command.

Key points

  • Keystore vs truststore: same file format, different role — keystore = my identity (-genkeypair output), truststore = who I trust (-importcert of CA certs). Configured via javax.net.ssl.keyStore / javax.net.ssl.trustStore system properties or framework config (Spring Boot server.ssl.*, Quarkus/Micronaut equivalents).
  • cacerts: the JDK's default truststore at $JAVA_HOME/lib/security/cacerts (historic default password changeit), pre-loaded with public CAs. Corporate TLS-intercepting proxies and internal CAs mean importing your CA there — or better, into a copy referenced via -Djavax.net.ssl.trustStore, so JDK upgrades don't lose it.
  • Generate a keypair: keytool -genkeypair -alias srv -keyalg EC -groupname secp256r1 (or -keyalg RSA -keysize 3072) -validity 365 -keystore ks.p12 -storetype PKCS12 — add -ext san=dns:myhost because modern clients validate SAN, not CN.
  • CSR round-trip: -certreq produces the CSR for a CA; -importcert the issued cert back onto the same alias (chain first or bundled), completing the chain.
  • Inspection: keytool -list -v -keystore ks.p12; keytool -printcert -sslserver host:443 fetches and prints a live server's chain — the quickest "what cert is it actually serving" check without OpenSSL.
  • TLS debugging moves: PKIX path building failed → the truststore lacks the issuing CA (find it with -printcert -sslserver, import it); wrong-host failures → check SANs with -list -v; deeper: run with -Djavax.net.ssl.debug=ssl:handshake.
  • OpenSSL interop: PKCS12 both ways — keytool -importkeystore converts, and OpenSSL-made .p12 bundles (e.g. from Let's Encrypt PEMs) load directly.

Examples

keytool -genkeypair -alias srv -keyalg EC -groupname secp256r1 \
        -validity 365 -dname 'CN=api.example.com' -ext san=dns:api.example.com \
        -keystore server.p12 -storetype PKCS12
keytool -importcert -alias corp-ca -file corp-root.pem -keystore trust.p12 -storetype PKCS12
keytool -printcert -sslserver api.example.com:443

Related