# Convert PEM to a Java keystore

There is no direct PEM-to-JKS conversion, because `keytool` cannot import a private key from a PEM file. The route is two steps: bundle the PEM certificate and key into a PKCS#12 archive with `openssl pkcs12 -export -in certificate.crt -inkey private.key -certfile chain.crt -name myalias -out keystore.p12`, then import that with `keytool -importkeystore -srckeystore keystore.p12 -srcstoretype PKCS12 -destkeystore keystore.jks -deststoretype JKS`. On Java 9 and later you should usually stop after the first step and use the PKCS#12 file directly, since it is the default keystore type and JKS is deprecated.

Source: https://certguru.io/convert/pem-to-jks/
Last updated: 2026-08-19
Commands verified against OpenSSL 3.5.7.

---

## Step 1 — PEM to PKCS#12 with OpenSSL

*Bundle certificate, key and chain, and name the alias*

```bash
openssl pkcs12 -export \
  -in certificate.crt \
  -inkey private.key \
  -certfile chain.crt \
  -name myalias \
  -out keystore.p12
```

| Placeholder | What to put there |
| --- | --- |
| `-name myalias` | The alias the entry gets inside the keystore. Set it now; renaming later is awkward. |
| `-certfile chain.crt` | Intermediate certificates. Omit if you have none, but a chain is usually required. |
| `keystore.p12` | The PKCS#12 archive. On Java 9+ this may be your final artefact. |

> **You may be finished here**
>
> Java 9 made PKCS#12 the default keystore type, and `keytool` warns that JKS is a proprietary
>   format every time you touch one. If the application reading this keystore runs on a modern JRE,
>   point it at `keystore.p12` with `storetype="PKCS12"` and skip step 2 entirely.

## Step 2 — PKCS#12 to JKS with keytool

*Import into a JKS keystore*

```bash
keytool -importkeystore \
  -srckeystore keystore.p12 -srcstoretype PKCS12 \
  -destkeystore keystore.jks -deststoretype JKS \
  -srcalias myalias -destalias myalias
```

`keytool` prompts for the destination keystore password, then the source (PKCS#12) password.

## Verify the result

```bash
keytool -list -v -keystore keystore.jks
```

Expected output:

```
Alias name: myalias
Entry type: PrivateKeyEntry
Certificate chain length: 2
Certificate[1]:
Owner: CN=example.com
Issuer: CN=Example Intermediate CA, O=Example CA, C=US
Valid from: ... until: ...
```

Three things to check in that output:

- **`Entry type: PrivateKeyEntry`** — if it says `trustedCertEntry`, the private key did not come
  across and the keystore cannot terminate TLS.
- **`Certificate chain length`** — should be at least 2 for a publicly trusted certificate. A length
  of 1 means the intermediates are missing and clients will report
  [unable to get local issuer certificate](/errors/unable-to-get-local-issuer-certificate/).
- **The alias** — must match what your application configuration expects.

## Importing a trusted CA instead

If you only need Java to *trust* a CA, and there is no private key involved, skip PKCS#12 entirely:

```bash
keytool -importcert -trustcacerts \
  -alias corp-root \
  -file root-ca.crt \
  -keystore truststore.jks
```

> **A truststore is not a keystore**
>
> A truststore holds CA certificates you are willing to trust. A keystore holds your own identity —
>   a certificate plus its private key. Putting one where the other is expected produces errors that
>   point at TLS handshakes rather than at the configuration mistake.

## Going the other way

See [convert JKS to PEM](/convert/jks-to-pem/).


## Frequently asked questions

### Why can't keytool import a PEM private key directly?

`keytool -importcert` imports certificates only. It has never had a way to read a private key from a PEM file, which is why the PKCS#12 detour exists. This has not changed in any Java release.

### Should I still be using JKS?

Probably not. Java 9 made PKCS#12 the default keystore type, and keytool prints a migration warning every time it touches a JKS file. Unless something specifically demands JKS, stop after the PKCS#12 step and point your application at the .p12.

### What does the alias do?

It names the entry inside the keystore. Java applications frequently need it in configuration to select which key to use, so set it deliberately with `-name` at export time rather than accepting the default of `1`.

### Do the two passwords have to match?

The keystore password and the key password are separate in JKS. Many Java servers, Tomcat among them, assume they are the same and fail confusingly when they are not. Setting both to the same value avoids a class of problems that is tedious to diagnose.


## References

- [keytool reference](https://docs.oracle.com/en/java/javase/21/docs/specs/man/keytool.html) — the Java keystore tool and its import options
- [RFC 7292: PKCS #12](https://www.rfc-editor.org/rfc/rfc7292) — the archive format, including the MAC OpenSSL 3 rejects on legacy files

## Related pages

- https://certguru.io/convert/jks-to-pem/
- https://certguru.io/convert/pfx-to-jks/
- https://certguru.io/errors/pkix-path-building-failed/
- https://certguru.io/convert/pem-to-pfx/
- https://certguru.io/formats/jks-keystore/
- https://certguru.io/platforms/tomcat/

--
CertGuru — https://certguru.io
