Search code examples
javatomcatkerberos

Migration from RC4 to AES256 Kerberos problems - Tomcat 9.0.64


Hi I tried to migrate our Java application from RC4 to AES256 encryption by generating new keytab.

To generate keytab I used ktutil:

addent -password -p HTTP/my.host@MY.DOMAIN -k 1 -e aes256-cts-hmac-sha1-96

For user I have changed parameter type to: msds-supportedEncryptionType = 24 (0x18)

and set SPN to HTTP/my.host@MY.DOMAIN

Also changed in krb5.conf to:

        default_tkt_enctypes = aes256-cts-hmac-sha1-96 aes128-cts-hmac-sha1-96
        default_tgs_enctypes = aes256-cts-hmac-sha1-96 aes128-cts-hmac-sha1-96
        permitted_enctypes = aes256-cts-hmac-sha1-96 aes128-cts-hmac-sha1-96

For kerberos logs I am using following parameters: -Dsun.security.krb5.debug=true -Dsun.security.jgss.debug=true -Dsun.security.spnego.debug=true

Unfortunately I am getting 401 error with Windows authentication box appearing.

In code I get following logs:

Debug is true storeKey true useTicketCache false useKeyTab true doNotPrompt true ticketCache is null isInitiator false KeyTab is /location/tomcat/base/conf/kerberos.keytab refreshKrb5Config is false principal is HTTP/my.host@MY.DOMAIN tryFirstPass is false useFirstPass is false storePass is false clearPass is false
principal is HTTP/my.host@MY.DOMAIN
Will use keytab
Commit Succeeded
Search Subject for SPNEGO ACCEPT cred (<<DEF>>, sun.security.jgss.spnego.SpNegoCredElement)
Search Subject for Kerberos V5 ACCEPT cred (<<DEF>>, sun.security.jgss.krb5.Krb5AcceptCredential)
Found KeyTab /location/tomcat/base/conf/kerberos.keytab for HTTP/my.host@MY.DOMAIN
Found KeyTab /location/tomcat/base/conf/kerberos.keytab for HTTP/my.host@MY.DOMAIN
Entered SpNegoContext.acceptSecContext with state=STATE_NEW
SpNegoContext.acceptSecContext: receiving token = a0 82 08 b7 30 82 08 b3 a0 30 30 2e 06 09 2a 86 48 ...
SpNegoToken NegTokenInit: reading Mechanism Oid = 1.2.840.113554.1.2.2
SpNegoToken NegTokenInit: reading Mechanism Oid = 1.2.840.48018.1.2.2
SpNegoToken NegTokenInit: reading Mechanism Oid = 1.3.6.1.4.1.311.2.2.30
SpNegoToken NegTokenInit: reading Mechanism Oid = 1.3.6.1.4.1.311.2.2.10
SpNegoToken NegTokenInit: reading Mech Token
SpNegoContext.acceptSecContext: received token of type = SPNEGO NegTokenInit
SpNegoContext: negotiated mechanism = 1.2.840.113554.1.2.2
Entered Krb5Context.acceptSecContext with state=STATE_NEW
Looking for keys for: HTTP/my.host@MY.DOMAIN
Added key: 18version: 1
>>> EType: sun.security.krb5.internal.crypto.Aes256CtsHmacSha1EType
[Krb5LoginModule]: Entering logout
[Krb5LoginModule]: logged out Subject

As you see above after adding key it entering logout. Unfortunately I don't get any error here and it not clear for me why it is not working. Previously with RC4 encoding it was working correctly.

Tomcat: 9.0.64 Java: 1.8.0_322-b06


Solution

  • Since you had RC4, I suspect you're using Active Directory as your Kerberos KDC.

    While Kerberos RC4-HMAC keys were completely unsalted (they were literally an NT-style MD4 hash), the AES128 or AES256 keys do use a salt as part of the (new) PBKDF2 key derivation.

    In "standard" MIT Kerberos, the salt is based directly on the principal name, i.e. HTTP/my.host is converted to the salt. However, that's not the case with Active Directory, where a single account could have multiple SPNs while sharing a single key between them – instead, AD creates the salt based on the account's "sAMAccountName" (which is probably something like tomcat123).

    The most likely result here is that the keys derived by ktutil don't match keys derived by your AD DC because of the mismatching salts. To fix this, use the addent -f option to make ktutil ask the KDC about what salt to use (the same way as would be done during 'kinit' or other ticket acquisition).