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
PEMEncoder
class for encoding cryptographic objects to PEM, and aPEMDecoder
class for decoding PEM data into cryptographic objects. A new marker interface namedDEREncodable
has been added, and existing classes such asX509Certificate
andX509CRL
have been retrofitted to implement this interface, thereby making it easier to encode/decode these objects to/from PEM.PEMEncoder
can also be configured for encryption which makes it easier to encrypt and encode private keys in one step. Similarly,PEMDecoder
can be configured for decryption to allow private keys to be decoded and decrypted in one step. For more advanced usage, the existingEncryptedPrivateKeyInfo
class 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
X509Certificate
retrieved from aKeyStore
to 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
PrivateKey
with a password and then encoding it into PEM. The first example configuresPEMEncoder
for 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
EncryptedPrivateKeyInfo
class 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
MessageDigest
algorithms have been added to theSUN
provider: 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
MessageDigest
to 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
SunPKCS11
provider. These algorithms can be used with the newKDF
API 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
, orKeyPairGenerator
APIs. Two subsections distinguish betweenAsymmetric
andSecretKey
(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
AlgorithmParameters
implementation is supported by theSunJCE
provider.Issue: JDK-8348405
TLS
-
Support for TLS Keying Material Exporters
New methods have been added to the
javax.net.ssl.ExtendedSession
class 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 SSLKeyException
The first method exports the keying material as a
SecretKey
and the second method as a byte array. TheSecretKey
method 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.disabledAlgorithms
security 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
UsageConstraint
to have a newUsageType
component, ex:UsageConstraint: usage UsageType { UsageType } UsageType: HandshakeSignature | CertificateSignature
The algorithm name can be a
Signature
algorithm (ex: SHA1withRSA), aKey
algorithm (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.disabledAlgorithms
security property in thejava.security
configuration 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
KEM
implementation has been improved by 1-2%.Issue: JDK-8347608
-
Optimize Java Implementation of ML-DSA
The performance of the ML-DSA
Signature
implementation 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
Cipher
implementation 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.UnresolvedPermission
javax.net.ssl.SSLPermission
javax.security.auth.AuthPermission
javax.security.auth.PrivateCredentialPermission
javax.security.auth.kerberos.DelegationPermission
javax.security.auth.kerberos.ServicePermission
com.sun.security.jgss.InquireSecContextPermission
java.lang.RuntimePermission
java.lang.reflect.ReflectPermission
java.io.FilePermission
java.io.SerializablePermission
java.nio.file.LinkPermission
java.util.logging.LoggingPermission
java.util.PropertyPermission
jdk.jfr.FlightRecorderPermission
java.net.NetPermission
java.net.URLPermission
jdk.net.NetworkPermission
com.sun.tools.attach.AttachPermission
com.sun.jdi.JDIPermission
java.lang.management.ManagementPermission
javax.management.MBeanPermission
javax.management.MBeanTrustPermission
javax.management.MBeanServerPermission
javax.management.remote.SubjectDelegationPermission
In addition, the
getPermission
method defined injava.net.URLConnection
and its subclassjava.net.HttpURLConnection
has 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.debug
system 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.debug
property is now documented in the javadoc. This is a very useful property for debugging security code.Issue: JDK-8328914