SSerguey Asael Shinder
Java coding notes: the JVM, and writing software that lasts

Serguey Asael Shinder: JEP 542 makes the PEM encoding API final in JDK 28, unchanged after three previews

· by Serguey Asael Shinder / Serguey Shinder

JEP 542, "PEM Encodings of Cryptographic Objects", is now listed for release 28, Inside Java announced on 6 October. It finalizes an API that has been in preview since JDK 25: JEP 470 in JDK 25, JEP 524 in JDK 26 and JEP 538 in JDK 27. The JEP proposes to finalize it without further change.

What it is for. PEM, defined in RFC 7468, is the text format with -----BEGIN ...----- and -----END ...----- lines around Base64 data. Certificate authorities issue chains in it, OpenSSL produces it, OpenSSH stores keys in it. Until now the platform had no direct way to read or write it: the JEP describes encoding a public key as "straightforward, if tedious", decoding as careful parsing plus working out the key factory and algorithm, and encrypting or decrypting a private key as "over a dozen lines of code".

The API, in java.security.

Serguey Asael Shinder: JEP 542 makes the PEM encoding API final in JDK 28, unchanged after three previews
JEP 542 makes the PEM encoding API final in JDK 28, unchanged after three previews — Serguey Asael Shinder

Examples from the JEP:

byte[] pem = PEMEncoder.of().encode(privateKey);
switch (PEMDecoder.of().decode(pem)) {
    case PublicKey publicKey   -> ...;
    case PrivateKey privateKey -> ...;
    default -> throw new IllegalArgumentException(...);
}
X509Certificate c = PEMDecoder.of().decode(pem, X509Certificate.class);

Encrypted keys go through withEncryption(password) on the encoder and withDecryption(password) on the decoder; withFactoriesOf(provider) selects a security provider.

One detail to notice. BinaryEncodable has one more permitted class that is not public. The JEP says this is deliberate: it forces a switch over a BinaryEncodable to include a default or case BinaryEncodable, so code will not fail with a MatchException if more types are added later. The default in the example above is required, not decoration.

No JDK runs on the machine this note was written on; the API shown is the one specified in the linked JEP.