# 8. PEM encodings (JEP 538, third preview) Prev: [7. Structured concurrency](07-structured-concurrency.md) · Next: [9. JFR redaction and the Vector API](09-jfr-redaction-and-vector.md) Compile and run with `--enable-preview --release 27`. Source: [`PemDemo`](../jep-tour/src/PemDemo.java), transcript [24](output/24-pem.txt). PEM is the `-----BEGIN ...-----` text format that every key and certificate file on a Linux box uses. The preview API replaces hand-rolled Base64 and header strings: ```java String pem = PEMEncoder.of().encodeToString(keyPair.getPublic()); // -----BEGIN PUBLIC KEY----- PublicKey back = PEMDecoder.of().decode(pem, PublicKey.class); String enc = PEMEncoder.of().withEncryption(password).encodeToString(privateKey); // ENCRYPTED PRIVATE KEY ``` Each round trip is asserted in the demo, including: without the password `decode` returns a still-encrypted `EncryptedPrivateKeyInfo`; with `withDecryption(password)` you get the original key back. ## The trap: `new PEM(type, byte[])` does not Base64-encode The bytes you pass are treated as the **already Base64-encoded** content and written between the header and footer verbatim ([24](output/24-pem.txt): the demo prints `hello, pem` in clear between `BEGIN ANKURM DEMO` and `END ANKURM DEMO`). To get a valid PEM, Base64-encode first and pass that; then `content()` is the Base64 text and `decode()` gives your payload back. This cost a failed assertion while writing this repository. ## What moved between 26 and 27 [`Pem26Style.java`](../jep-tour/src/broken/Pem26Style.java) compiles on 26 and produces three errors on 27 ([20-broken-pem26style.txt](output/20-broken-pem26style.txt)): `DEREncodable` became `BinaryEncodable`; `PEMDecoder.withFactory(Provider)` is gone; `PEM.content()` now returns `byte[]` rather than `String`. Prev: [7. Structured concurrency](07-structured-concurrency.md) · Next: [9. JFR redaction and the Vector API](09-jfr-redaction-and-vector.md)