JDK 25 was released on September 16, 2025! As with my previous blogs, I have compiled a list of what I think are the most interesting and useful security enhancements in this release. I have also grouped them into appropriate categories (crypto, TLS, etc) which should make it easier to find out what has changed in each specific area. The JDK 25 release notes also contain further details on these and other enhancements.
Highlights of this release include a final version of the Key Derivation Function API and a new preview API for encoding and decoding cryptographic objects to/from PEM.
Table of Contents
Crypto
-
JEP 470: PEM Encodings of Cryptographic Objects (Preview)
A new preview API for encoding and decoding cryptographic objects to/from the PEM format has been introduced in JDK 25 and defined in JEP 470. PEM is a widely used format for transferring and storing DER-encoded cryptographic data such as certificates, CRLs, private keys, and more. This was one of the most commonly requested features in a JCE survey a few years ago.
Two primary APIs have been added, a
PEMEncoderclass for encoding cryptographic objects to PEM, and aPEMDecoderclass for decoding PEM data into cryptographic objects. A new marker interface namedDEREncodablehas been added, and existing classes such asX509CertificateandX509CRLhave been retrofitted to implement this interface, thereby making it easier to encode/decode these objects to/from PEM.PEMEncodercan also be configured for encryption which makes it easier to encrypt and encode private keys in one step. Similarly,PEMDecodercan be configured for decryption to allow private keys to be decoded and decrypted in one step. For more advanced usage, the existingEncryptedPrivateKeyInfoclass has also been enhanced with several new methods that make it easier to encrypt and decrypt private keys.Here is an example of encoding an
X509Certificateretrieved from aKeyStoreto PEM:X509Certificate cert = (X509Certificate)keystore.getCertificate("mycert"); PEMEncoder encoder = PEMEncoder.of(); String pem = encoder.encodeToString(cert);Here is an example of decoding the PEM back into an
X509Certificate:PEMDecoder decoder = PEMDecoder.of(); X509Certificate cert = decoder.decode(pem, X509Certificate.class);Here are two examples of encrypting a
PrivateKeywith a password and then encoding it into PEM. The first example configuresPEMEncoderfor encryption and encrypts and encodes the private key directly in one method call:PEMEncoder encoder = PEMEncoder.of(); String pem = encoder.withEncryption(password).encodeToString(privateKey);The above example uses default parameters when encrypting. This second example uses the
EncryptedPrivateKeyInfoclass to encrypt the private key with additional parameters such as the password-based encryption algorithm, and then encodes it to PEM:EncryptedPrivateKeyInfo epki = EncryptedPrivateKeyInfo.encryptKey(privateKey, password, "PBEWithHmacSHA256AndAES_256", null, null); PEMEncoder encoder = PEMEncoder.of(); String pem = encoder.encodeToString(epki); -
JEP 510: Key Derivation Function API
A preview of the Key Derivation Function (KDF) API was delivered in JDK 24 and defined in JEP 478. This release delivers the final version of the API, without any changes. KDF is an API for deriving keys from key material and is more fully described in JEP 510. Also included is an implementation of the HMAC-based Extract-and-Expand Key Derivation Function (HKDF), which is defined in RFC 5869.
KDF will be a very valuable API for several future enhancements that depend on key derivation. These include PQC mechanisms such as Hybrid Key Exchange in TLS 1.3 (IETF Draft) and Hybrid Public Key Encryption (RFC 9180). The API is also designed to be used for strong and modern password-based algorithms such as Argon2 (RFC 9106).
The main new class is
javax.crypto.KDF. The JEP gives an example of using the HKDF-SHA256 algorithm to derive a 32 byte AES key:// Create a KDF object for the specified algorithm KDF hkdf = KDF.getInstance("HKDF-SHA256"); // Create an ExtractExpand parameter specification AlgorithmParameterSpec params = HKDFParameterSpec.ofExtract() .addIKM(initialKeyMaterial) .addSalt(salt).thenExpand(info, 32); // Derive a 32-byte AES key SecretKey key = hkdf.deriveKey("AES", params); -
SHAKE128-256 and SHAKE256-512 MessageDigest Algorithms
Two new
MessageDigestalgorithms have been added to theSUNprovider: SHAKE128-256 and SHAKE256-512. These are fixed-length versions of the SHAKE128 and SHAKE256 Extendable-Output Functions (XOFs) defined in NIST FIPS 202.Here is an example using
MessageDigestto digest some bytes with SHAKE128-256:byte[] bytes = ... MessageDigest md = MessageDigest.getInstance("SHAKE128-256"); byte[] digest = md.digest(bytes);Issue: JDK-8354305
-
PKCS#11 Support for the HKDF-SHA256, HKDF-SHA384 and HKDF-SHA512 Key Derivation Function Algorithms
Support for the HKDF-SHA256, HKDF-SHA384 and HKDF-SHA512 Key Derivation Function algorithms has been added to the
SunPKCS11provider. These algorithms can be used with the newKDFAPI in JDK 25. See the SunPKCS11 Provider Supported Algorithms section of the PKCS#11 Reference Guide for more details.Issue: JDK-8328119
-
Added TLSv1.3 and CNSA 1.0 Algorithms to Implementation Requirements
In the Java Security Standard Algorithm Names Specification, new requirements have been added to the list of cryptographic requirements all Java SE implementations must support. All cryptographic algorithms that are needed to implement the TLSv1.3 cipher suites and signature mechanisms and that are defined by RFC 8446 as MUST or SHOULD requirements have been added. All algorithms that are required by CNSA 1.0 have also been added. No required algorithms or protocols are being removed at this time. These are the new requirements:
AlgorithmParameters- ChaCha20-Poly1305
- EC with secp256r1 or secp384r1 curves
- RSASSA-PSS with MGF1 mask generation function and SHA-256 or SHA-384 hash algorithm
Cipher- AES/GCM/NoPadding with 256 bit key size
- ChaCha20-Poly1305
KeyAgreement- ECDH with secp256r1 or secp384r1 curves
- X25519
KeyFactory- EC
- RSASSA-PSS
- X25519
KeyGenerator- AES with 256 bit key size
- ChaCha20
KeyPairGenerator- DH with 3072 bit key size
- EC with secp256r1 or secp384r1 curves
- RSA with 3072 bit key size
- RSASSA-PSS with 2048, 3072, 4096 bit key sizes
- X25519
MessageDigest- SHA-384
Signature- RSASSA-PSS with MGF1 mask generation function and SHA-256 or SHA-384 hash algorithm
- SHA256WithECDSA with secp256r1 curve
- SHA384WithECDSA with secp384r1 curve
- SHA384WithRSA
SSLContext- TLSv1.3
Issue: JDK-8283795
-
New Key Algorithms Section of the Java Security Standard Algorithm Names Specification
A new Key Algorithms section has been added to the Java Security Standard Algorithm Names Specification listing the standard names of keys generated or created by the
KeyFactory,SecretKeyFactory,KeyGenerator, orKeyPairGeneratorAPIs. Two subsections distinguish betweenAsymmetricandSecretKey(or symmetric) algorithms.Issue: JDK-8346736
-
Added PBES2 as a Standard AlgorithmParameters Algorithm
PBES2 had been added as a standard algorithm to the AlgorithmParameters section of the Java Security Standard Algorithm Names Specification. The PBES2 algorithm is defined in PKCS #5: Password-Based Cryptography Specification, Version 2.1. A PBES2
AlgorithmParametersimplementation is supported by theSunJCEprovider.Issue: JDK-8348405
TLS
-
Support for TLS Keying Material Exporters
New methods have been added to the
javax.net.ssl.ExtendedSessionclass that allow applications to generate additional application-level keying material from a connection’s negotiated TLS keys.These new APIs are useful for various exporter mechanisms that depend on keying material, such as those listed in the TLS Exporter Labels section of the IANA registry.
Two new methods have been added:
public SecretKey exportKeyingMaterialKey(String keyAlg, String label, byte[] context, int length) throws SSLKeyException public byte[] exportKeyingMaterialData( String label, byte[] context, int length) throws SSLKeyExceptionThe first method exports the keying material as a
SecretKeyand the second method as a byte array. TheSecretKeymethod is useful for implementations that store keys on hardware or tokens.Issue: JDK-8341346
-
New Mechanism to Disable Signature Schemes Based on Their TLS Scope
The
jdk.tls.disabledAlgorithmssecurity property has been enhanced to support selectively disabling algorithms in TLS handshake or certificate signatures. This new syntax allows you to more easily disable an algorithm only for handshake signatures or only for certificate signatures, which might be desirable depending on various factors.The syntax extends the existing
UsageConstraintto have a newUsageTypecomponent, ex:UsageConstraint: usage UsageType { UsageType } UsageType: HandshakeSignature | CertificateSignatureThe algorithm name can be a
Signaturealgorithm (ex: SHA1withRSA), aKeyalgorithm (ex: RSA), or a TLS signature scheme (ex: rsa_pkcs1_sha1).Issue: JDK-8349583
-
Disabled SHA-1 in TLS 1.2 and DTLS 1.2 Handshake Signatures
SHA-1 in TLS 1.2 and DTLS 1.2 handshake signatures is now disabled by default. SHA-1 is deprecated for use in handshake signatures as specified in RFC 9155.
Users can re-enable SHA-1 in handshake signatures, at their own risk, by removing “rsa_pkcs1_sha1 usage HandshakeSignature, ecdsa_sha1 usage HandshakeSignature, dsa_sha1 usage HandshakeSignature” from the
jdk.tls.disabledAlgorithmssecurity property in thejava.securityconfiguration file.Issue: JDK-8353879
Performance Improvements
Several performance improvements have been made to the crypto and TLS implementations:
-
Optimize Java Implementation of ML-KEM
The performance of the ML-KEM
KEMimplementation has been improved by 1-2%.Issue: JDK-8347608
-
Optimize Java Implementation of ML-DSA
The performance of the ML-DSA
Signatureimplementation has been improved by approximately 10%.Issue: JDK-8347606
-
Change ChaCha20 Intrinsic to use Quarter-Round Parallel Implementation on aarch64
The performance of the ChaCha20
Cipherimplementation has been improved by 2-4% on aarch64 processors.Issue: JDK-8349106
-
Reduce TLS Stateless Session Ticket Size
The size of TLS stateless session tickets has been significantly reduced.
Issue: JDK-8357033
Security Manager
-
Various Permission Classes Deprecated for Removal
Many permission classes have been deprecated for removal as they are no longer useful now that the Security Manager has been permanently disabled in JDK 24. The following classes are now terminally deprecated:
java.security.UnresolvedPermissionjavax.net.ssl.SSLPermissionjavax.security.auth.AuthPermissionjavax.security.auth.PrivateCredentialPermissionjavax.security.auth.kerberos.DelegationPermissionjavax.security.auth.kerberos.ServicePermissioncom.sun.security.jgss.InquireSecContextPermissionjava.lang.RuntimePermissionjava.lang.reflect.ReflectPermissionjava.io.FilePermissionjava.io.SerializablePermissionjava.nio.file.LinkPermissionjava.util.logging.LoggingPermissionjava.util.PropertyPermissionjdk.jfr.FlightRecorderPermissionjava.net.NetPermissionjava.net.URLPermissionjdk.net.NetworkPermissioncom.sun.tools.attach.AttachPermissioncom.sun.jdi.JDIPermissionjava.lang.management.ManagementPermissionjavax.management.MBeanPermissionjavax.management.MBeanTrustPermissionjavax.management.MBeanServerPermissionjavax.management.remote.SubjectDelegationPermission
In addition, the
getPermissionmethod defined injava.net.URLConnectionand its subclassjava.net.HttpURLConnectionhas been deprecated for removal.Issue: JDK-8348967
Miscellaneous
-
Turn on Timestamp and Thread Details by Default for java.security.debug
The “thread” and “timestamp” options that were added to the
java.security.debugsystem property in JDK 23 are now on by default.Each debug statement will now also include the thread id, thread name, caller information (source code and line number) and the date and time.
For example, below is a portion of the output of an application run with
-Djava.security.debug=properties:
properties[0x1|main|Security.java:161|2024-09-20 09:31:39.929]: java.security properties[0x1|main|Security.java:122|2024-09-20 09:31:39.931]: Initial security property: jdk.jar.disabledAlgorithms=MD2, MD5, RSA keySize < 1024, DSA keySize < 1024, SHA1 denyAfter 2019-01-01 properties[0x1|main|Security.java:122|2024-09-20 09:31:39.931]: Initial security property: security.provider.13=SunPKCS11 properties[0x1|main|Security.java:122|2024-09-20 09:31:39.931]: Initial security property: security.provider.12=Apple properties[0x1|main|Security.java:122|2024-09-20 09:31:39.931]: Initial security property: http.auth.digest.disabledAlgorithms=MD5, SHA-1 properties[0x1|main|Security.java:122|2024-09-20 09:31:39.932]: Initial security property: jdk.security.legacyAlgorithms=SHA1, RSA keySize < 2048, DSA keySize < 2048, DES, DESede, MD5, RC2, ARCFOUR properties[0x1|main|Security.java:122|2024-09-20 09:31:39.932]: Initial security property: securerandom.source=file:/dev/random
Issue: JDK-8350689
-
Javadoc for the java.security.debug Property
The
java.security.debugproperty is now documented in the javadoc. This is a very useful property for debugging security code.Issue: JDK-8328914