JDK 26 was released on March 17, 2026! 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 26 release notes also contain further details on these and other enhancements.
Highlights of this release include a second preview of the PEM API, API support for Hybrid Public Key Encryption, and signed JAR support for the post-quantum ML-DSA algorithm.
Table of Contents
Crypto
-
Hybrid Public Key Encryption
We have added support for Hybrid Public Key Encryption, or HPKE. HPKE is a modern encryption scheme for encrypting arbitrary-sized plaintexts with a recipient’s public key. HPKE is defined in RFC 9180. It combines 3 different algorithms, a KEM, KDF, and an AEAD (authenticated encryption with associated data) algorithm to produce a ciphertext.
To use HPKE in your applications, you use the existing
CipherAPI with a newHPKEParameterSpecclass which specifies the KEM, KDF, and AEAD algorithms you want to use.Initially in JDK 26, we only support traditional, non-PQC algorithms. However, we plan to add support for PQC algorithms in a later JDK release once the Internet draft on Post-Quantum and Post-Quantum/Traditional Hybrid Algorithms for HPKE becomes an RFC.
This example from the
HPKEParameterSpecjavadoc shows a sender and a recipient using HPKE to securely exchange messages with an X25519 key pair:// Recipient key pair generation KeyPairGenerator g = KeyPairGenerator.getInstance("X25519"); KeyPair kp = g.generateKeyPair(); // The HPKE sender cipher is initialized with the recipient's public // key and an HPKEParameterSpec using specified algorithm identifiers // and application-supplied info. Cipher senderCipher = Cipher.getInstance("HPKE"); HPKEParameterSpec ps = HPKEParameterSpec.of( HPKEParameterSpec.KEM_DHKEM_X25519_HKDF_SHA256, HPKEParameterSpec.KDF_HKDF_SHA256, HPKEParameterSpec.AEAD_AES_128_GCM) .withInfo(HexFormat.of().parseHex("010203040506")); senderCipher.init(Cipher.ENCRYPT_MODE, kp.getPublic(), ps); // Retrieve the key encapsulation message (from the KEM step) from // the sender. byte[] kemEncap = senderCipher.getIV(); // The HPKE recipient cipher is initialized with its own private key, // an HPKEParameterSpec using the same algorithm identifiers as used by // the sender, and the key encapsulation message from the sender. Cipher recipientCipher = Cipher.getInstance("HPKE"); HPKEParameterSpec pr = HPKEParameterSpec.of( HPKEParameterSpec.KEM_DHKEM_X25519_HKDF_SHA256, HPKEParameterSpec.KDF_HKDF_SHA256, HPKEParameterSpec.AEAD_AES_128_GCM) .withInfo(HexFormat.of().parseHex("010203040506")) .withEncapsulation(kemEncap); recipientCipher.init(Cipher.DECRYPT_MODE, kp.getPrivate(), pr); // Encryption and decryption byte[] msg = "Hello World".getBytes(StandardCharsets.UTF_8); byte[] ct = senderCipher.doFinal(msg); byte[] pt = recipientCipher.doFinal(ct); assert Arrays.equals(msg, pt);Issue: JDK-8325448
-
PKCS#12 KeyStore support for RFC 9879: Use of Password-Based Message Authentication Code 1 (PBMAC1)
The JDK PKCS12
KeyStoreimplementation now supports the more modern PBMAC1 algorithm for integrity protection. To use the PBMAC1 algorithm, set thekeystore.pkcs12.macAlgorithmproperty in thejava.securityconfiguration file to a PBMAC1 algorithm, for example, “PBEWithHmacSHA256”. Existing PKCS12 keystore files will continue to use the integrity algorithm it was created with, but new keystore files will use the PBMAC1 algorithm.In a future JDK release, the default value of the
keystore.pkcs12.macAlgorithmsecurity property will be changed to a PBMAC1 algorithm.Issue: JDK-8343232
-
JEP 524: PEM Encodings of Cryptographic Objects (Second Preview)
The second preview API for encoding and decoding cryptographic objects to/from the PEM format was delivered and defined in JEP 524. 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. The History section of the JEP contains a list of changes since the first preview.
There are two primary APIs, a
PEMEncoderclass for encoding cryptographic objects to PEM, and aPEMDecoderclass for decoding PEM data into cryptographic objects. There is also a marker interface namedDEREncodable, 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 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.encrypt(privateKey, password, "PBEWithHmacSHA256AndAES_256", null, null); PEMEncoder encoder = PEMEncoder.of(); String pem = encoder.encodeToString(epki); -
New Security Property to Disable Algorithms at the JCE Layer
A new security property named
jdk.crypto.disabledAlgorithmshas been added which can be used to disable cryptographic algorithms at the JCE/JCA API level. This property takes a list of algorithm names as specified in the Standard Algorithm Names specification. The security property can be overridden by a system property of the same name.Initially the property is empty and contains no algorithms.
This is a very useful property which allows you to detect usage of cryptographic algorithms at a comprehensive level across all code in your application.
For more details on the syntax of the algorithm and the JCE services that are supported, see the definition in the
java.securityconfiguration file.Issue: JDK-8244336
-
Various Performance Improvements
A number of performance improvements in the AES, ML-DSA and Elliptic Curve (P256) algorithms were made. See the following issues for more details:
-
Removed Obsolete Algorithms from Implementation Requirements
The DESede (3DES) algorithms and Cipher algorithms using PKCS1Padding have been removed from the implementation requirements of Java SE. These algorithms are no longer recommended and should not be requirements. The complete list of requirements removed is:
AlgorithmParameters: DESede Cipher: DESede/CBC/NoPadding DESede/CBC/PKCS5Padding DESede/ECB/NoPadding DESede/ECB/PKCS5Padding RSA/ECB/PKCS1Padding KeyGenerator: DESede SecretKeyFactory: DESedeIssue: JDK-8361964
-
Added PBES2 Algorithms as New Implementation Requirements
The following PBES2 algorithms from RFC 8018: PKCS #5: Password-Based Cryptography Specification Version 2.1 have been added as new requirements:
AlgorithmParameters: PBEWithHmacSHA256AndAES_128 PBEWithHmacSHA256AndAES_256 Cipher: PBEWithHmacSHA256AndAES_128 PBEWithHmacSHA256AndAES_256 Mac: PBEWithHmacSHA256 SecretKeyFactory: PBEWithHmacSHA256AndAES_128 PBEWithHmacSHA256AndAES_256 PBKDF2WithHmacSHA256Issue: JDK-8361964
PKI
-
New Root CA Certificates
Several new root CA certificates have been added to the
cacertskeystore:- Four Sectigo root CA certificates, two for TLS, and two for code signing:
- Sectigo Public Server Authentication Root E46 with the following distinguished name:
CN=Sectigo Public Server Authentication Root E46, O=Sectigo Limited, C=GB - Sectigo Public Server Authentication Root R46 with the following distinguished name:
CN=Sectigo Public Server Authentication Root R46, O=Sectigo Limited, C=GB - Sectigo Public Code Signing Root E46 with the following distinguished name:
CN=Sectigo Public Code Signing Root E46, O=Sectigo Limited, C=GB - Sectigo Public Code Signing Root R46 with the following distinguished name:
CN=Sectigo Public Code Signing Root R46, O=Sectigo Limited, C=GB
These root certificates have also been added to the
cacertskeystore in Oracle’s JDK 25, 24.0.2, 21.0.8, 17.0.16, 11.0.27, and 8u461 releases.Issue: JDK-8359170
- Sectigo Public Server Authentication Root E46 with the following distinguished name:
- Four Sectigo root CA certificates, two for TLS, and two for code signing:
-
Removed Root CA Certificates
Four AffirmTrust root certificates have been removed from the
cacertskeystore. These root CAs were deactivated by Entrust (who owns them) and will no longer be supported. The four roots are:- AffirmTrust Commercial with the following distinguished name:
CN=AffirmTrust Commercial, O=AffirmTrust, C=US - AffirmTrust Networking with the following distinguished name:
CN=AffirmTrust Networking, O=AffirmTrust, C=US - AffirmTrust Premium with the following distinguished name:
CN=AffirmTrust Premium, O=AffirmTrust, C=US - AffirmTrust Premium ECC with the following distinguished name:
CN=AffirmTrust Premium ECC, O=AffirmTrust, C=US
These root certificates have also been removed from the
cacertskeystore in Oracle’s JDK 25.0.1, 21.0.9, 17.0.17, 11.0.29, and 8u471 releases.Issue: JDK-8361212
- AffirmTrust Commercial with the following distinguished name:
TLS
-
Improved Checking in SunX509
KeyManagerFactoryThe default SunX509
KeyManagerFactory, which is used to provide certificates and key material for TLS connections, has been improved. It now implements additional checks on certificates to ensure the ones that are selected are compliant with current algorithm constraints settings. This makes its checking consistent with the PKIXKeyManagerFactory.Specifically, selection is based on the following rules:
- Local certificates are checked against peer supported certificate
signature algorithms sent with the TLS
signature_algorithms_certextension. - Local certificates are checked against TLS algorithm constraints
specified in the
jdk.tls.disabledAlgorithmsandjdk.certpath.disabledAlgorithmssecurity properties. - Local certificates are prioritized based on validity period and certificate extensions.
The prior behavior can be re-enabled by setting the system property
jdk.tls.SunX509KeyManager.certCheckingtotrue.Issue: JDK-8359956
- Local certificates are checked against peer supported certificate
signature algorithms sent with the TLS
XML Signature
-
Disabled the XPath Filtering Transform
XML Signatures that use the XPath Filtering Transform have been disabled by default. The XPath transform, while powerful, has a higher risk of introducing complexities and is not recommended in the XML Signature Best Practices document. If necessary, and at your own risk, the transform can be re-enabled by removing it from the
jdk.xml.dsig.secureValidationPolicysecurity property.Alternatively, users should consider replacing their usages with the XPath Filter 2 Transform, which was designed to address the issues associated with the XPath Filtering Transform.
Issue: JDK-8314180
-
New Property to Specify
SecureRandomA new XML Signature property named
jdk.xmldsig.SecureRandomhas been added which allows you to specify a specificSecureRandominstance to use instead of the defaultSecureRandomthat the JDK implementation uses.This can be useful if you want more control over the secure random numbers used in the generation of XML Signatures.
To use this property, you call the
setPropertymethod of theXMLSignContextclass with the property name and the instance of theSecureRandomobject you would like to use.Issue: JDK-8359395
Tools
-
Signed JAR Support for ML-DSA
In JDK 21, we added support ML-DSA, which is a quantum-resistant digital signature algorithm specified by NIST in FIPS 204 and defined in JEP 497 for the Java Platform.
In this release, we have extended that support and added support for signing JARs with ML-DSA. This can be done using the
jarsignerutility or theJarSignerAPI.Here is an example of using ML-DSA to sign a JAR with
jarsigner:$ jarsigner -keystore ks –sigalg ML-DSA-65 -signedjar signed.jar test.jar mldsaIssue: JDK-8349732
-
java -XshowSettings:security:tlsNow Shows TLS Named Groups and Signature SchemesThe
java -XshowSettings:security:tlsdiagnostic command now shows the TLS named groups (or key exchange algorithms) and signature schemes that are enabled for TLS handshakes, in addition to the enabled protocols and cipher suites.Here is a sample run showing the new output:
$ java -XshowSettings:security:tls Security TLS configuration (SunJSSE provider): Enabled Protocols: TLSv1.3 TLSv1.2 Enabled Cipher Suites: TLS_AES_256_GCM_SHA384 TLS_AES_128_GCM_SHA256 TLS_CHACHA20_POLY1305_SHA256 TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256 TLS_DHE_DSS_WITH_AES_256_GCM_SHA384 TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 TLS_DHE_DSS_WITH_AES_128_GCM_SHA256 TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 TLS_DHE_DSS_WITH_AES_256_CBC_SHA256 TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 TLS_DHE_DSS_WITH_AES_128_CBC_SHA256 TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA TLS_DHE_RSA_WITH_AES_256_CBC_SHA TLS_DHE_DSS_WITH_AES_256_CBC_SHA TLS_DHE_RSA_WITH_AES_128_CBC_SHA TLS_DHE_DSS_WITH_AES_128_CBC_SHA TLS_EMPTY_RENEGOTIATION_INFO_SCSV Enabled Named Groups: X25519MLKEM768 x25519 secp256r1 secp384r1 secp521r1 x448 ffdhe2048 ffdhe3072 ffdhe4096 ffdhe6144 ffdhe8192 Enabled Signature Schemes: ecdsa_secp256r1_sha256 ecdsa_secp384r1_sha384 ecdsa_secp521r1_sha512 ed25519 ed448 rsa_pss_rsae_sha256 rsa_pss_rsae_sha384 rsa_pss_rsae_sha512 rsa_pss_pss_sha256 rsa_pss_pss_sha384 rsa_pss_pss_sha512 rsa_pkcs1_sha256 rsa_pkcs1_sha384 rsa_pkcs1_sha512 dsa_sha256 ecdsa_sha224 rsa_sha224 dsa_sha224 ecdsa_sha1 rsa_pkcs1_sha1 dsa_sha1Issues: JDK-8351354, JDK-8371074
-
Improved
keytoolWarning When Using JKS or JCEKS KeystoresThe warning that
keytoolprints when a JKS or JCEKS keystore is used has been improved to alert users that these keystores will eventually be removed and also recommend migrating the keystores to PKCS12. The warning emitted for JKS is now the following:"JKS uses outdated cryptographic algorithms and will be removed in a future release. Migrate to PKCS12 using: keytool -importkeystore -srckeystore <filename> -destkeystore <filename> -deststoretype pkcs12"The warning for JCEKS is the same.
Issue: JDK-8353749