JDK 18 was released on March 22, 2022! 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, PKI, etc) which should make it easier to find out what has changed in each specific area. The JDK 18 release notes also contain further details on these and other enhancements.
Highlights of this release include further improvements that strengthen the default security of the Java Platform, support for new crypto algorithms, and new alternative JAAS APIs that do not depend on deprecated Security Manager APIs. See below for more details on these and other enhancements.
Several performance improvements have also been made in the crypto, TLS and JAAS/Kerberos components. See JDK-8270317, JDK-8276660, JDK-8273299, JDK-8268427, JDK-8267125, and JDK-8273026 for more details.
Also, one other important JDK 18 feature that is not part of the security libraries area but is definitely worth mentioning is:
-
JEP 421: Deprecate Finalization for Removal
This JEP deprecates finalization for removal in a future release. Finalizers can cause various security issues and require special care when using. More robust replacements and techniques are already available and are listed in the JEP.
Table of Contents
Crypto
-
PKCS#11 support for AES Key Wrap and AES Key Wrap With Padding (KWP) modes
The
SunPKCS11
provider now supports the AES Key Wrap and AES Key Wrap With Padding (KWP) cipher modes if the underlying PKCS11 native library supports them.These standard modes are designed to protect cryptographic keys and are defined in NIST SP 800-38F.
This enhancement builds on the enhancement in JDK 17 which added and improved support for these modes to the
SunJCE
provider.Use these modes in your Java application with the
javax.crypto.Cipher
API with the algorithm transformations"AES/KW/NoPadding"
,"AES/KW/PKCS5Padding"
or"AES/KWP/NoPadding"
.The JCE algorithm mappings to the PKCS11 mechanisms are as follows:
AES/KW/NoPadding Cipher => CKM_AES_KEY_WRAP mechanism AES/KW/PKCS5Padding Cipher => CKM_AES_KEY_WRAP_PAD mechanism AES/KWP/NoPadding Cipher => CKM_AES_KEY_WRAP_KWP mechanism
See the PKCS#11 Reference Guide for more information about PKCS#11 support in the JDK.
Issue: JDK-8264849
-
New
KeyStore::getAttributes()
APIA new
getAttributes(String alias)
method has been added to thejava.security.KeyStore
API. This method returns a set of attributes associated with a KeyStore alias, or entry. Before this change, the attributes of an entry could only be obtained by calling thegetAttributes
method of aKeyStore.Entry
. If the entry was aPrivateKeyEntry
, the application needed to provide the proper password to unlock the entry, even if the attributes associated with the entry were not protected. This new API avoids that issue.A corresponding
engineGetAttributes(String alias)
method has also been added to theKeyStoreSpi
class for providers to implement. If not overridden by a provider, theKeyStore::getAttributes
method will return an empty set. Third party providers should add support for this API when adding support for JDK 18.See the Key Management section of the JCA Reference Guide for more information about KeyStores.
Issue: JDK-8225181
-
A passwordless PKCS12 keystore is now easier to create
Passwordless keystores (a keystore with no password required to unlock it) are useful when the keystore is stored in a secure location and is only intended to store non-sensitive information, such as public X.509 certificates. With a passwordless PKCS12 keystore, certificates are not encrypted and there is no Mac applied as an integrity check is not necessary.
Prior to this change, creating a passwordless PKCS12 keystore was difficult, and required setting various security properties. Now, a passwordless PKCS12 keystore can be created by simply specifying a
null
password to theKeyStore::store(outStream, password)
API. The keystore can then be loaded with a null (or any) password with theKeyStore::load()
API.Issue: JDK-8231107
PKI
-
The
cacerts
keystore is now in PKCS12 formatThe
cacerts
keystore, which holds the root CA certificates bundled with the JDK, has been converted from the non-standard JKS format to the standard PKCS12 format.This change has several benefits. It moves
cacerts
away from the obsolete JKS format. And it transitionscacerts
to the PKCS12 format which supports a passwordless keystore – this means that you no longer have to specify (or change) the default password “changeit”, unless you intend to store sensitive material within it.See the Crypto section for more details on passwordless keystores.
Issue: JDK-8275252
-
OCSP responses support for RSASSA-PSS
OCSP responses signed with the RSASSA-PSS signature algorithm are now supported.
Issue: JDK-8274471
-
Removal of Google’s GlobalSign Root Certificate
The “GlobalSign” Root CA certificate is now expired and has been removed from the
cacerts
keystore. This root certificate is owned by Google and has the following distinguished name:CN=GlobalSign, O=GlobalSign, OU=GlobalSign Root CA - R2
This root certificate has also been removed from the
cacerts
keystore in Oracle’s JDK 17.0.2, 11.0.14, 8u321, and 7u331 releases.Issue: JDK-8225083
-
Removal of IdenTrust Root Certificate
The “DST Root CA X3” Root CA certificate is now expired and has been removed from the
cacerts
keystore. This root certificate is owned by IdenTrust and has the following distinguished name:CN=DST Root CA X3, O=Digital Signature Trust Co.
This root certificate has also been removed from the
cacerts
keystore in Oracle’s JDK 17.0.1, 11.0.13, 8u311, and 7u321 releases.Issue: JDK-8225082
Kerberos
-
Weak encryption types (DES, 3DES, RC4) have been removed from the default list of Kerberos encryption types
The DES, 3DES, and RC4 encryption types have been removed from the default list of Kerberos encryption types. Note that these weak encryption types were already disabled by default prior to this release, and would not be used unless the
allow_weak_crypto
property was set totrue
in thekrb5.conf
file, but once that was done, any of the weak encryption types could then be used. With this change, in order to use them, you have to also specifically add the weak algorithm(s) that you want to use to thepermitted_enctypes
property (or alternatively, thedefault_tkt_enctypes
ordefault_tgt_enctypes
properties) in thekrb5.conf
file.Re-enabling these weak encryption types is not recommended and should be done at your own risk.
See the Kerberos 5 GSS-API Mechanism Guide for more information on the supported
krb5.conf
properties.Issue: JDK-8273670
-
The
krb5.conf
default_checksum
andsafe_checksum_type
properties are no longer supportedThe
default_checksum
andsafe_checksum_type
properties in thekrb5.conf
configuration file are no longer supported.The checksum type used in TGS-REQ requests is derived from the encryption type and therefore the
default_checksum
property is no longer necessary.The
safe_checksum_type
property specifies the type of checksum to use for KRB-SAFE requests and was never used directly by the JDK.Issue: JDK-8274656
Security Manager
-
New APIs for Subject based authorization that do not depend on the Security Manager
In JDK 17, as specified in JEP 411, the Security Manager was deprecated for removal. As part of that change, several Security Manager APIs were deprecated for removal, such as
AccessControlContext
. The JAASSubject::doAs()
andSubject::getSubject()
APIs depend on Security Manager related APIs, even though they do not require a Security Manager to be installed to use them.These APIs are important for developers that want to write secure applications that authorize subjects and perform sensitive operations based on their credentials. Thus, JEP 411 outlined plans to provide replacement JAAS APIs that did not have dependencies on Security Manager APIs.
These replacement JAAS APIs have now been added to JDK 18.
Subject::callAs()
is a replacement forSubject::doAs()
, andSubject::current()
is a replacement forSubject::getSubject()
. The usage of these new replacement APIs is similar and simpler than the previous APIs. For example, here is an example of code using the old APIs:
Subject s1 = new Subject(); Subject.doAs(s1, (PrivilegedExceptionAction<Void>)() -> { AccessControlContext acc = AccessController.getContext(); Subject s2 = Subject.getSubject(acc); return null; });
using the new APIs, this code now looks like:
Subject s1 = new Subject(); Subject.callAs(s1, () -> { Subject s2 = Subject.current(); return null; });
With the addition of these new APIs, the
Subject::doAs()
methods have been deprecated for removal.Subject::getSubject()
was already deprecated for removal in JDK 17.See the JAAS Reference Guide for more information about JAAS.
Issue: JDK-8267108
-
New default for the
java.security.manager
system propertyJEP 411 also announced that we would be changing the default value of the
java.security.manager
system property fromallow
todisallow
in JDK 18. This change improves the performance of applications that do not run with a Security Manager.The implication of this change means that applications that dynamically install a Security Manager (by calling
System::setSecurityManager()
) must now explicitly set thejava.security.manager
system property toallow
on the command-line, for example as follows:
java -Djava.security.manager=allow MyApp
Issue: JDK-8270380
Tools
-
New
keytool
andjarsigner
--version
optionA new option named
--version
has been to thekeytool
andjarsigner
tools. If specified, it will print the JDK version that the tool is using. Here is an example:
$ keytool --version keytool 18
See the keytool and jarsigner tool specifications for more details about these tools.
Issue: JDK-8272163
Signed JARs
-
SHA-1 JARs are disabled by default
JARs signed with SHA-1 algorithms are now disabled by default. SHA-1 is a digest algorithm that has become increasingly weak and should no longer be used for digital signatures.
With this change, maintaining compatibility with previously signed JARs was an important consideration, so the restrictions do not apply to SHA-1 JARs that have been timestamped before 2019-01-01. However, this compatibility constraint is subject to change so it is in your best interest to re-sign any SHA-1 JARs with stronger algorithms.
If a JAR is signed with SHA-1 and does not meet the compatibility constraints above, then it will be restricted and treated as if it were unsigned. This applies to the algorithms used to digest and sign the JAR, as well as the signer’s certificate chain and any revocation data such as CRLs or signed OCSP responses. If the JAR is timestamped, it also applies to the timestamp digest and the TSA’s certificate chain and any revocation data.
This change is also planned to be backported to Oracle’s update releases later in the year – check the Java Crypto Roadmap for the latest status and targeted dates.
The
jarsigner
tool has also been enhanced to more accurately detect and warn you if your JAR is affected by these restrictions. We encourage you to use this tool to see if your JARs are affected. Here is an example ofjarsigner
when used to verify a SHA-1 JAR that violates the restrictions (note that SHA-1 as the Digest algorithm is flagged as “(disabled)” and a warning is emitted byjarsigner
):
$ jarsigner -verify -verbose signed.jar 57 Tue Mar 22 14:25:08 EDT 2022 META-INF/MANIFEST.MF 249 Tue Mar 22 14:25:08 EDT 2022 META-INF/SIGNER.SF 2005 Tue Mar 22 14:25:08 EDT 2022 META-INF/SIGNER.RSA m ? 1 Tue Mar 22 14:24:16 EDT 2022 A s = signature was verified m = entry is listed in manifest k = at least one certificate was found in keystore ? = unsigned entry - Signed by "CN=signer" Digest algorithm: SHA-1 (disabled) Signature algorithm: SHA256withRSA, 2048-bit key WARNING: The jar will be treated as unsigned, because it is signed with a weak algorithm that is now disabled by the security property: jdk.jar.disabledAlgorithms=MD2, MD5, RSA keySize < 1024, DSA keySize < 1024, SHA1 denyAfter 2019-01-01
Issue: JDK-8269039