Skip to main content

    Java Keytool Commands Cheat Sheet: Keystore, CSR, Import and Trust

    Every keytool command you need: build a PKCS12 keystore, generate a CSR that carries SAN, import the CA reply into the right alias, and migrate off JKS.

    DR
    Daniel Rehak
    ·
    16 min read
    ·
    Published August 11, 2026
    ·
    Last updated August 11, 2026

    The short answer

    Four commands carry a certificate from nothing to serving: -genkeypair creates the key, -certreq writes the CSR, -importcert installs the CA's reply, and -list -v proves it worked. Two details break more Java installs than everything else combined. The SAN extension does not travel from -genkeypair to -certreq, so -ext SAN=… has to be repeated on the request. And the signed certificate has to be imported into the same alias that generated the request, because importing it under a new alias returns success and stores something no server can use. Since JDK 9 the default keystore type is PKCS12, and JKS now warns on every command.

    The four keytool stages of getting a publicly trusted certificate into a Java keystore, and the two stages where it silently goes wrongA left-to-right sequence of four stages. Stage one, keytool -genkeypair, creates the private key and a self-signed placeholder under an alias. Stage two, keytool -certreq, writes the certificate signing request, and is highlighted in gold as a failure point because the subject alternative name extension does not carry over from stage one and must be repeated with the -ext argument. Stage three is the certificate authority, which validates the request and returns a signed certificate and its chain. Stage four, keytool -importcert, is highlighted in gold as the second failure point because the reply must be imported into the same alias used in stage one; importing it under a new alias succeeds without any error but stores it as a trusted certificate entry that no server can use. A band underneath contrasts the two success messages keytool prints: Certificate reply was installed in keystore, which means the private key and the signed certificate are now paired, versus Certificate was added to keystore, which means only a trusted certificate was stored.One round trip, four commands, two places it fails quietlySTAGE 1-genkeypairprivate key createdunder an aliasalias: serverSTAGE 2 — WATCH-certreqSAN does not carryover from stage 1repeat -ext SAN=…STAGE 3the CAvalidates the requestreturns cert + chain.crt / .p7bSTAGE 4 — WATCH-importcertmust reuse thestage 1 aliasalias: serverRead the message keytool prints at stage 4. The two are not synonyms.WHAT YOU WANTCertificate reply was installedin keystoreThe signed certificate is now paired withyour private key. Entry stays PrivateKeyEntry.WHAT MEANS YOU MISSEDCertificate was added to keystoreYou imported under a new alias. It stored atrustedCertEntry with no key attached, exitcode 0, and no server can serve it.Verify rather than trust the exit codekeytool -list -v -alias server -keystore server.p12 → Entry type: PrivateKeyEntry, chain length ≥ 2
    Both gold stages accept bad input and return success, which is why a Java certificate install can look finished on the terminal and still serve the old self-signed certificate to every client.

    Every command below was run against OpenJDK 21 in August 2026, and the messages quoted are the ones keytool actually printed rather than the ones the documentation implies. Where behaviour differs between Java versions, the difference is called out.

    What keytool actually manages

    keytool manages entries inside keystore files, and there are only two kinds of entry: a PrivateKeyEntry, which is your own key plus the certificate chain that vouches for it, and a trustedCertEntry, which is someone else's certificate you have decided to accept. A keystore and a truststore are the same file format doing opposite jobs, separated only by which entries they hold and which JVM property points at them.

    Keystore, truststore and cacerts compared: what each file holds and which JVM property points at itThree panels side by side. The first, the keystore, holds your own private key and the signed certificate that proves it, stores them as a PrivateKeyEntry, is pointed at by the javax.net.ssl.keyStore property, and answers the question of what identity this server presents. The second, the truststore, holds other parties' certificates you have chosen to believe, stores them as trustedCertEntry, is pointed at by javax.net.ssl.trustStore, and answers the question of whose identity this client accepts. The third, cacerts, is the truststore that ships with the JDK, sits at JAVA_HOME slash lib slash security slash cacerts on Java 9 and later, has the default password changeit, and is reachable with the keytool -cacerts flag. A band underneath notes that all three are ordinary PKCS12 files and that keytool cannot tell you which job a file is doing, which is why the two are so often confused.Same file format, opposite jobsKEYSTORE"who am I?"Holdsyour private key +its signed certificateEntry typePrivateKeyEntryJVM propertyjavax.net.ssl.keyStoreused by serversTRUSTSTORE"who do I believe?"Holdsother parties' CA orleaf certificatesEntry typetrustedCertEntryJVM propertyjavax.net.ssl.trustStoreused by clientscacertsthe JDK's own truststoreWhere$JAVA_HOME/lib/security/cacerts (Java 9+)PasswordchangeitShortcutkeytool -list -cacertsno path neededAll three are ordinary PKCS12 fileskeytool will not tell you which job a file is doing. The entry type is the only honest signal, so read it before you debug anything else.
    A Java client that cannot reach an internal API almost always has a truststore problem, and a Java server presenting the wrong certificate almost always has a keystore problem. Naming which one you are looking at saves the first hour.

    That distinction is worth holding onto because it splits Java TLS problems in half before you start debugging. A Java service that cannot connect to something has a truststore question. A Java service presenting the wrong certificate to its own clients has a keystore question. The commands are similar enough that people reach for the wrong one under pressure.

    An alias is a name, not a label. Every entry in a keystore lives under an alias, and keytool uses it as the primary key for almost every operation. Aliases are case-insensitive and permanent for practical purposes: renaming one means -changealias, and application config files usually name the alias explicitly, so a rename is a config change too.

    JKS or PKCS12: which format in 2026?

    PKCS12, without reservation. It has been the default keystore type since JDK 9 under JEP 229, it is a published standard (RFC 7292) rather than a Java-specific container, and it is the format certificate authorities actually deliver. On Java 21, opening a JKS keystore prints a warning on every command recommending you migrate. Existing JKS files keep working, so this is a housekeeping task rather than an outage waiting to happen.

    JKS compared with PKCS12 across five properties that matter when choosing a Java keystore formatA five-row comparison table with JKS on the left and PKCS12 on the right. Row one, standing: JKS is a Java-only proprietary format, while PKCS12 is published as RFC 7292 and is the row highlighted in gold because it is the default keystore type from JDK 9 onward. Row two, tooling: JKS is readable by Java tools only, PKCS12 is readable by OpenSSL, Windows, Nginx tooling and Java alike. Row three, what the CA sends: certificate authorities deliver PFX and PKCS12 bundles, not JKS. Row four, behaviour on Java 21: a JKS keystore prints a proprietary-format warning on every command and prompts separately for a key password, while PKCS12 is silent. Row five, migration: one keytool -importkeystore command converts a JKS in place and leaves a dot-old backup file behind.There is no longer a decision to make herePROPERTYJKSPKCS12StandingJava-only, proprietaryno longer the defaultRFC 7292 standarddefault type since JDK 9ToolingJava tools onlyOpenSSL, Windows, JavaWhat the CA shipsnever a .jks.pfx / .p12 bundlesOn Java 21warns on every command,asks for a second passwordsilentGetting from A to Bkeytool -importkeystore -srckeystore app.jks \ -destkeystore app.jks -deststoretype pkcs12The in-place migration keeps the original as app.jks.old, so it is reversible.
    If a guide opens by telling you to create a .jks file, it predates JDK 9 and the rest of its advice is worth double-checking.

    The warning text is specific enough to copy, and it names the command that fixes it:

    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".

    Running that migration in place converts the file and keeps the original next to it:

    keytool -importkeystore \
      -srckeystore app.jks \
      -destkeystore app.jks \
      -deststoretype pkcs12
    
    # Entry for alias legacy successfully imported.
    # Import command completed:  1 entries successfully imported, 0 entries failed or cancelled
    # Warning:
    # Migrated "app.jks" to PKCS12. The JKS keystore is backed up as "app.jks.old".

    One practical difference worth knowing before you migrate: JKS supports a separate password on each key, and PKCS12 does not treat them independently in the same way. If your application config carries a distinct key password, expect to set it equal to the store password after the conversion. There is also a small comfort in the .old backup — the operation is reversible if a downstream tool turns out to need the original.

    Creating a keystore and a key pair

    One command creates both: keytool generates the key pair, wraps it in a self-signed placeholder certificate, and writes the keystore file if it does not exist yet. The placeholder is temporary scaffolding that gets replaced when the CA's reply comes back. Pick the alias deliberately, because you will need it again at every later step.

    keytool -genkeypair \
      -alias server \
      -keyalg RSA -keysize 2048 \
      -sigalg SHA256withRSA \
      -storetype PKCS12 \
      -keystore server.p12 \
      -validity 365 \
      -dname "CN=www.example.com,O=Example GmbH,L=Berlin,C=DE" \
      -ext "SAN=dns:www.example.com,dns:example.com"

    -storetype PKCS12 is redundant on Java 9 and later and harmless everywhere, so it is worth leaving in for scripts that might run on an older JVM. -dname supplied inline keeps the command non-interactive, which matters the moment this ends up in a pipeline. Leave -keysize in as well: JDK 21 defaults RSA to 3072 bits when you omit it, which is fine cryptographically but slower on every handshake and larger than anything a public CA requires.

    ECDSA instead of RSA. Swap in -keyalg EC -groupname secp256r1 -sigalg SHA256withECDSA. The keys are far smaller and the handshake is cheaper, and every current browser and Java runtime handles P-256. Some older middleware in front of your Java app may not, which is the real reason RSA is still the safe default in an enterprise estate. The trade-off is laid out in ECC compared with RSA for TLS certificates.

    A word on -genkey: it still works and does the same thing, because it is the legacy spelling of -genkeypair. Older documentation is full of it. Writing -genkeypair in anything new costs nothing and says what it does.

    Generating a CSR, and the SAN trap

    keytool -certreq builds the request from the entry's subject name, and it does not copy the extensions you set when you generated the key. Requesting a certificate for more than one host name means repeating the whole -ext SAN=… argument here. Since public certificate authorities validate against the SAN extension and browsers ignore the common name entirely, a request without SAN either comes back covering one name or gets rejected.

    keytool -certreq \
      -alias server \
      -keystore server.p12 \
      -file server.csr \
      -ext "SAN=dns:www.example.com,dns:example.com"

    It is worth seeing what the omission looks like, because keytool gives you no hint. Generating a key pair with two SAN names and then running -certreq without -ext on JDK 21 produces a request whose only extension is a Subject Key Identifier:

    $ openssl req -in server.csr -noout -text
    
    # Without -ext on the -certreq command:
            Attributes:
                Requested Extensions:
                    X509v3 Subject Key Identifier:
                        C3:1D:41:5A:85:F9:D0:6D:69:EA:DE:09:DA:B8:48:A9:7E:10:46:C1
    
    # With -ext "SAN=dns:www.example.com,dns:example.com":
            Attributes:
                Requested Extensions:
                    X509v3 Subject Key Identifier:
                        C3:1D:41:5A:85:F9:D0:6D:69:EA:DE:09:DA:B8:48:A9:7E:10:46:C1
                    X509v3 Subject Alternative Name:
                        DNS:www.example.com, DNS:example.com

    Make that check part of the routine. One openssl req -noout -text before submitting costs a few seconds and catches the mistake while it is still free, rather than after validation has run and a reissue is the only way back. If OpenSSL is not installed on the machine, the free CSR and certificate decoders in the My-SSL tool set read the same fields in a browser. For what each field in a request means, our explanation of CSR contents covers the whole structure.

    Submit the resulting file to your certificate authority. A domain-validated certificate usually comes back within minutes; an organization-validated one waits on the CA confirming the company exists, which is normally one to three working days. My-SSL issues DV, OV and EV certificates through Certum, and every one of them accepts a keytool-generated request as long as the SAN names are in it.

    Importing the certificate the CA sends back

    Import the reply into the same alias that generated the request, with -trustcacerts, and only once the issuing chain is reachable from the keystore. Get the alias right and keytool replaces the self-signed placeholder with the real certificate. Get it wrong and keytool stores the certificate as a separate trusted entry, prints a success message, and exits zero.

    Three outcomes when importing a signed certificate back into a Java keystore, with the exact message keytool prints for eachThree stacked outcomes. The first, importing into a new alias, prints Certificate was added to keystore and exits zero, but stores a trustedCertEntry with no private key, so the server keeps serving whatever it served before. The second, importing into the correct alias while the issuing chain is not reachable, fails loudly with keytool error java.lang.Exception Failed to establish chain from reply, which is the helpful failure because it stops you. The third, importing the root or the full chain first and then the reply into the original alias, prints Certificate reply was installed in keystore, and a verbose listing then shows entry type PrivateKeyEntry with a certificate chain length of two or more. Only the third outcome produces a keystore a server can use.Same file, same command, three very different results1 · IMPORTED INTO A NEW ALIAS — the silent onekeytool -importcert -alias server-2026 -file server.crt -keystore server.p12Certificate was added to keystoreExit code 0 · stored as trustedCertEntry · no private key attached · nothing changes for clients2 · RIGHT ALIAS, CHAIN NOT REACHABLE — the honest failurekeytool -importcert -alias server -file server.crt -keystore server.p12keytool error: java.lang.Exception: Failed to establish chain from replyNon-zero exit · import the intermediate and root first, or import the CA's full .p7b bundle3 · CHAIN FIRST, THEN THE REPLY INTO THE ORIGINAL ALIAS — the one you wantkeytool -importcert -alias root -trustcacerts -file root.crt -keystore server.p12keytool -importcert -alias server -trustcacerts -file server.p7b -keystore server.p12Certificate reply was installed in keystoreVerify: keytool -list -v -alias server → Entry type: PrivateKeyEntry · Certificate chain length: 2Messages reproduced from a JDK 21 run against a locally signed request.
    Outcome 1 is the expensive one because it looks like outcome 3 on the terminal. Checking the entry type afterwards takes a second and separates them for good.

    The order matters. If the CA sent a P7B or a full-chain bundle, one import does everything. If it sent separate PEM files, the root and intermediates go in first, each under its own alias, then the leaf goes into the original alias:

    # 1 — the chain, root first, each under its own alias
    keytool -importcert -alias caroot -trustcacerts -file root.crt   -keystore server.p12
    keytool -importcert -alias caint  -trustcacerts -file inter.crt  -keystore server.p12
    
    # 2 — the reply, into the SAME alias that generated the CSR
    keytool -importcert -alias server -trustcacerts -file server.crt -keystore server.p12
    # -> Certificate reply was installed in keystore
    
    # 3 — prove it before you restart anything
    keytool -list -v -alias server -keystore server.p12 | grep -E "Entry type|chain length"
    # -> Entry type: PrivateKeyEntry
    # -> Certificate chain length: 2

    "Failed to establish chain from reply" is the good outcome. It means you used the correct alias and the only thing missing is the chain, so keytool refused rather than storing something broken. Import the intermediate, run the same command again, and it completes. The failure mode with no error message is the one that costs an afternoon. Missing intermediates cause the same class of problem on every platform, which the guide to certificate chains goes through in detail.

    When the certificate was issued somewhere else entirely and you have a PFX from the CA rather than a reply to your own request, skip -importcert altogether and import the whole keystore:

    keytool -importkeystore \
      -srckeystore certificate.pfx -srcstoretype PKCS12 \
      -destkeystore server.p12     -deststoretype PKCS12 \
      -srcalias 1 -destalias server

    The -srcalias value is whatever the PFX happens to use, often a GUID or the number 1. Run keytool -list -keystore certificate.pfx -storetype PKCS12 first to read it, and rename it on the way in with -destalias so your application config stays stable across renewals.

    Listing and inspecting what is in a keystore

    -list answers the two questions that matter after any change: what entries exist, and what type is each one. Adding -v expands a single entry into the full certificate, including the chain length and the validity dates. Adding -rfc prints the certificate as PEM instead, which is handy when you want to paste it into something else.

    CommandWhat it answers
    keytool -list -keystore server.p12Which aliases exist, and is each one a PrivateKeyEntry or a trustedCertEntry
    keytool -list -v -alias server -keystore server.p12Subject, issuer, SAN names, validity dates and chain length for one entry
    keytool -list -rfc -alias server -keystore server.p12The certificate as PEM text, ready to paste elsewhere
    keytool -printcert -file server.crtWhat is in a certificate file, without touching a keystore
    keytool -printcertreq -file server.csrWhat is in a CSR, including whether SAN made it in
    keytool -printcert -sslserver www.example.com:443What a live server is actually presenting right now

    That last one earns its place in a troubleshooting session. Comparing -printcert -sslserver against -list -v on the keystore tells you immediately whether the application picked up the file you edited, which is a different question from whether the file is correct. Applications cache keystores at startup more often than people expect.

    Converting, exporting, and getting the key out

    keytool exports certificates and refuses to export private keys. There is no flag for it and no plan to add one. When you need the key itself — moving a certificate from a Java app to Nginx, say — the supported route is to convert the keystore to PKCS12 with -importkeystore, then read the key out with OpenSSL.

    # Certificate only — keytool can do this
    keytool -exportcert -alias server -keystore server.p12 -rfc -file server.crt
    
    # Private key — keytool cannot, so hand it to OpenSSL
    keytool -importkeystore \
      -srckeystore server.jks -srcstoretype JKS \
      -destkeystore server.p12 -deststoretype PKCS12
    
    openssl pkcs12 -in server.p12 -nocerts -nodes  -out server.key
    openssl pkcs12 -in server.p12 -clcerts -nokeys -out server.crt
    openssl pkcs12 -in server.p12 -cacerts -nokeys -out chain.crt

    Going the other way, from PEM files into a keystore, has no single-step keytool command either. Build the PKCS12 with OpenSSL first and import it, which is also how you get a certificate bought for a web server into a Java application:

    openssl pkcs12 -export \
      -in server.crt -inkey server.key -certfile chain.crt \
      -name server -out server.p12
    
    keytool -importkeystore \
      -srckeystore server.p12 -srcstoretype PKCS12 \
      -destkeystore server.p12 -deststoretype PKCS12

    Two housekeeping notes. Files written by openssl pkcs12 -nodes hold an unencrypted private key, so they belong in a directory with restricted permissions and nowhere near version control. And on OpenSSL 3.x, reading an old PKCS12 file produced by legacy tooling sometimes needs the -legacy flag, because the RC2 and 40-bit RC4 algorithms those files use moved to the legacy provider. The wider set of format conversions lives in our OpenSSL commands cheat sheet, and the guide to PEM, PFX, DER and P7B explains which file you are looking at in the first place.

    Trust: cacerts and custom truststores

    Java ships its own truststore, cacerts, holding the public CA roots the JVM trusts by default. On Java 9 and later it lives at $JAVA_HOME/lib/security/cacerts; on Java 8 it sat one level deeper under jre/. The default password is changeit, and modern keytool gives you a -cacerts flag so you never have to type the path.

    # What does this JVM trust?
    keytool -list -cacerts -storepass changeit
    
    # Is one specific root in there?
    keytool -list -cacerts -storepass changeit | grep -i certum
    
    # Add a private or internal root (needs write access to the JDK)
    keytool -importcert -cacerts -storepass changeit \
      -alias internal-root -file internal-root.crt
    
    # Better: a project truststore you own, passed to the app at startup
    keytool -importcert -keystore truststore.p12 -storetype PKCS12 \
      -alias internal-root -file internal-root.crt
    
    java -Djavax.net.ssl.trustStore=/opt/app/truststore.p12 \
         -Djavax.net.ssl.trustStorePassword=... -jar app.jar

    Prefer the project truststore to editing cacerts. A JDK upgrade replaces the file and takes your additions with it, and on Debian and Ubuntu cacerts is usually a symlink into the distribution's certificate store, so a routine package update can do the same thing. A truststore that lives with the application survives both, and it is visible to whoever inherits the service.

    One caveat on custom truststores. Setting javax.net.ssl.trustStore replaces cacerts rather than adding to it. A truststore containing only your internal root will make the application reject every public certificate on the internet, which usually surfaces as an unrelated outbound API breaking an hour later. If the app talks to both, start from a copy of cacerts and add your root to that copy.

    Renewal now that certificates last 200 days

    Renewal is the same four commands, and the shortcut is to keep the existing key pair and alias: generate a fresh CSR from the entry you already have, then import the new reply over the old certificate in place. That keeps your application config untouched, which is the whole point when the job now recurs twice a year instead of annually.

    # Renewal on the existing alias — no new key, no config change
    keytool -certreq -alias server -keystore server.p12 -file renew.csr \
      -ext "SAN=dns:www.example.com,dns:example.com"
    
    # ... submit renew.csr, wait for the CA ...
    
    keytool -importcert -alias server -trustcacerts -file renewed.p7b -keystore server.p12
    keytool -list -v -alias server -keystore server.p12 | grep -E "Valid from|chain length"

    The dates behind that cadence come from CA/Browser Forum ballot SC-081v3. As of 15 March 2026 the maximum lifetime of a publicly trusted TLS certificate is 200 days; it drops to 100 days on 15 March 2027 and to 47 days on 15 March 2029. Certificate authorities issue slightly under each ceiling, so a certificate bought today expires in roughly six months. Reusing the same key pair every time is convenient, though rotating it at least annually is the healthier habit — and once the 47-day step lands, a manual keytool sequence eight times a year stops being viable and the question becomes automation instead. What the shorter lifetimes change in practice covers the schedule and its consequences.

    keytool errors and what they mean

    keytool's messages are terse and mostly accurate once you know what they are pointing at. These are the ones that come up repeatedly, with the cause rather than a restatement of the text.

    MessageWhat is actually wrong
    Failed to establish chain from replyThe alias is right, but the issuing chain is not in the keystore. Import the intermediate and root first, or import the CA's full P7B bundle instead of the bare leaf.
    Certificate was added to keystoreNot an error, and usually not what you wanted. You imported into an alias with no private key, so it was stored as a trusted certificate. Re-import into the original alias.
    Alias <server> does not existWrong keystore file, or the alias differs in a way you did not expect. Run -list and read the aliases before guessing.
    Keystore was tampered with, or password was incorrectNearly always the password. It also appears when the file is not a keystore at all, such as a PEM certificate renamed to .p12.
    The JKS keystore uses a proprietary formatInformational. The file still works; run the in-place -importkeystore migration when convenient and the warning stops.
    unable to find valid certification path to requested targetA runtime error rather than a keytool one, and it is a truststore problem: the JVM does not trust the certificate the other side presented. Add the issuing root to the truststore the app is actually using.
    No certificate matches the SAN / name mismatch at runtimeThe CSR went out without -ext SAN=…, so the issued certificate covers fewer names than you assumed. This needs a reissue, not a keystore edit.

    Quick reference

    Every command on this page in one block, in the order you would run them. Substitute your own alias, file names and host names; everything else is copy-ready.

    # ── CREATE ────────────────────────────────────────────────────────────────
    keytool -genkeypair -alias server -keyalg RSA -keysize 2048 \
      -storetype PKCS12 -keystore server.p12 -validity 365 \
      -dname "CN=www.example.com,O=Example GmbH,L=Berlin,C=DE" \
      -ext "SAN=dns:www.example.com,dns:example.com"
    
    # ── REQUEST (repeat -ext, it does not carry over) ─────────────────────────
    keytool -certreq -alias server -keystore server.p12 -file server.csr \
      -ext "SAN=dns:www.example.com,dns:example.com"
    openssl req -in server.csr -noout -text            # confirm SAN is present
    
    # ── IMPORT (chain first, reply into the ORIGINAL alias) ───────────────────
    keytool -importcert -alias caroot -trustcacerts -file root.crt   -keystore server.p12
    keytool -importcert -alias caint  -trustcacerts -file inter.crt  -keystore server.p12
    keytool -importcert -alias server -trustcacerts -file server.p7b -keystore server.p12
    
    # ── VERIFY ────────────────────────────────────────────────────────────────
    keytool -list -keystore server.p12
    keytool -list -v -alias server -keystore server.p12
    keytool -printcert -sslserver www.example.com:443
    
    # ── CONVERT ───────────────────────────────────────────────────────────────
    keytool -importkeystore -srckeystore app.jks \
      -destkeystore app.jks -deststoretype pkcs12          # JKS -> PKCS12, in place
    keytool -importkeystore -srckeystore certificate.pfx -srcstoretype PKCS12 \
      -destkeystore server.p12 -deststoretype PKCS12 -srcalias 1 -destalias server
    keytool -exportcert -alias server -keystore server.p12 -rfc -file server.crt
    openssl pkcs12 -in server.p12 -nocerts -nodes -out server.key   # key: OpenSSL only
    
    # ── TRUST ─────────────────────────────────────────────────────────────────
    keytool -list -cacerts -storepass changeit
    keytool -importcert -keystore truststore.p12 -storetype PKCS12 \
      -alias internal-root -file internal-root.crt
    
    # ── HOUSEKEEPING ──────────────────────────────────────────────────────────
    keytool -delete      -alias old-server -keystore server.p12
    keytool -changealias -alias server -destalias server-2026 -keystore server.p12
    keytool -storepasswd -keystore server.p12
    keytool -keypasswd   -alias server -keystore server.p12

    Java-specific signing work uses a different tool with the same keystore: jarsigner reads the PrivateKeyEntry you built here, which is covered in signing a JAR with jarsigner. For putting the finished keystore in front of traffic, the Tomcat installation guide and the GlassFish guide pick up where this one stops.

    Frequently Asked Questions

    Get instant answers to common questions about SSL certificates and our services.

    Still Have Questions?

    Our SSL experts are available 24/7 to help with any questions about certificates, installation, or technical issues.

    Getting the certificate itself

    keytool builds the request and installs the answer; the certificate in between comes from a certificate authority. SSL certificates from My-SSL are issued by Certum, whose roots have been in the Java cacerts store and the major browser trust stores for years, and a keytool-generated CSR is accepted as-is. If your deployment needs several host names on one keystore entry, order a multi-domain certificate and list every name in the -ext SAN= argument before you submit.

    Related reading