I have a productive Java application using Kerberos for SSO.
After I update Java from version 16 to 17, I run into the following Error:
Cannot find key of appropriate type to decrypt AP-REQ - RC4 with HMAC
Caused by: GSSException: Failure unspecified at GSS-API level (Mechanism level: Invalid argument (400) - Cannot find key of appropriate type to decrypt AP-REQ - RC4 with HMAC)
at java.security.jgss/sun.security.jgss.krb5.Krb5Context.acceptSecContext(Unknown Source)
at java.security.jgss/sun.security.jgss.GSSContextImpl.acceptSecContext(Unknown Source)
at java.security.jgss/sun.security.jgss.GSSContextImpl.acceptSecContext(Unknown Source)
at java.security.jgss/sun.security.jgss.spnego.SpNegoContext.GSS_acceptSecContext(Unknown Source)
at java.security.jgss/sun.security.jgss.spnego.SpNegoContext.acceptSecContext(Unknown Source)
at java.security.jgss/sun.security.jgss.GSSContextImpl.acceptSecContext(Unknown Source)
at java.security.jgss/sun.security.jgss.GSSContextImpl.acceptSecContext(Unknown Source)
at org.keycloak.federation.kerberos.impl.SPNEGOAuthenticator.establishContext(SPNEGOAuthenticator.java:169)
at org.keycloak.federation.kerberos.impl.SPNEGOAuthenticator$AcceptSecContext.run(SPNEGOAuthenticator.java:132)
at org.keycloak.federation.kerberos.impl.SPNEGOAuthenticator$AcceptSecContext.run(SPNEGOAuthenticator.java:122)
... 73 more
Caused by: KrbException: Invalid argument (400) - Cannot find key of appropriate type to decrypt AP-REQ - RC4 with HMAC
at java.security.jgss/sun.security.krb5.KrbApReq.authenticate(Unknown Source)
at java.security.jgss/sun.security.krb5.KrbApReq.<init>(Unknown Source)
at java.security.jgss/sun.security.jgss.krb5.InitSecContextToken.<init>(Unknown Source)
... 83 more
ktpass /crypto ALL
was used to create the keytab file.
Error Cause
After a bit of research I came across the following JDK 17 Security Enhancements:
Deprecate 3DES and RC4 in Kerberos
3DES and RC4 Kerberos encryption types have now been disabled by default. Both 3DES and RC4 are weak encryption algorithms that should not be used. The Kerberos 3DES and RC4 encryption types are officially deprecated in RFC 8429.
By default the des3-hmac-sha1 and rc4-hmac encryption types are now disabled, but can be re-enabled, at your own risk, by setting the allow_weak_crypto property to true in the krb5.conf configuration file. However, note that will also re-enable other weak encryption types that are already disabled such as des-cbc-crc and des-cbc-md5. Alternatively, set the default_tkt_enctypes, default_tgs_enctypes, and permitted_enctypes properties to the encryption types that are allowed.
Issue: JDK-8139348
Solution 1 - use AES 128/256 encryption:
The preferred solution is, to configure the AD/Kerberos to use AES 128 or 256 bit encryption.
Mostly the following seems to be enough, but there can be other configurations in the AD or GPOs that block AES encryption:
The service-user configured for kerberos (used to create the keytab file) needs the following configuration:
Afterwards on the machine running the java application, run:
klist purge
Solution 2 - workaround -> allow weak encryption
For I quick workaround (maybe you are not the admin of the AD or need to wait for a maintenance window) the following worked for me:
Create or use the existing krb5.conf file, add:
[libdefaults]
allow_weak_crypto=true
Start the java application using:
-Djava.security.krb5.conf=%CONF_LOCATION%/krb5.conf