SPNEGO/ActiveDirectory/AES256:校验和失败



我正在尝试将SPNEGO/Kerberos5身份验证与Active Directory 2008和Java一起使用。我遵循以下指南:http://spnego.sourceforge.net/-"飞行前"进行得很顺利,但后来我得到了一个著名的例外:

Exception in thread "main" GSSException: Failure unspecified at GSS-API level (Mechanism level: Checksum failed)
    at sun.security.jgss.krb5.Krb5Context.acceptSecContext(Krb5Context.java:856)
    at sun.security.jgss.GSSContextImpl.acceptSecContext(GSSContextImpl.java:342)
    at sun.security.jgss.GSSContextImpl.acceptSecContext(GSSContextImpl.java:285)
    at sun.security.jgss.spnego.SpNegoContext.GSS_acceptSecContext(SpNegoContext.java:906)
    at sun.security.jgss.spnego.SpNegoContext.acceptSecContext(SpNegoContext.java:556)
    at sun.security.jgss.GSSContextImpl.acceptSecContext(GSSContextImpl.java:342)
    at sun.security.jgss.GSSContextImpl.acceptSecContext(GSSContextImpl.java:285)
    at de.meona.auth.spnego.TestSpnegoAes.main(TestSpnegoAes.java:45)
Caused by: KrbException: Checksum failed
    at sun.security.krb5.internal.crypto.Aes256CtsHmacSha1EType.decrypt(Aes256CtsHmacSha1EType.java:102)

我仔细看了一下这篇帖子,因为问题似乎很相似:校验和失败:Kerberos/Spring/Active Directory(2008)

为了使问题能够重现,我编写了一个Java小类。我能够一步一步地走到发生异常的那一行。我认为这是因为用于解密的密钥与Active Directory用于加密服务票证的密钥不同。这怎么可能?

public class TestSpnegoAes {
    private static Oid spnegoOid = null;
    private static String negotiate = "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";
    private static GSSManager manager;
    // -Dsun.security.krb5.debug=true
    // -Djava.security.auth.login.config=login.conf
    public static void main(String[] args) throws GSSException, LoginException, PrivilegedActionException {
        spnegoOid = new Oid("1.3.6.1.5.5.2");
        manager = GSSManager.getInstance();
        LoginContext loginContext = new LoginContext("spnego-server");
        loginContext.login();
        Subject subject = loginContext.getSubject();
        GSSCredential serviceCredentials = getServerCredential(subject);
        GSSContext context = manager.createContext(serviceCredentials);
        byte[] token = Base64.decode(negotiate);
        context.acceptSecContext(token, 0, token.length);
    }
    static GSSCredential getServerCredential(final Subject subject) throws PrivilegedActionException {
        final PrivilegedExceptionAction<GSSCredential> action = new PrivilegedExceptionAction<GSSCredential>() {
            public GSSCredential run() throws GSSException {
                return manager.createCredential(null, GSSCredential.INDEFINITE_LIFETIME, spnegoOid,
                        GSSCredential.ACCEPT_ONLY);
            }
        };
        return Subject.doAs(subject, action);
    }
}

这是我的login.conf文件:

spnego-server {
    com.sun.security.auth.module.Krb5LoginModule required
    useKeyTab=true
    storeKey=true
    isInitiator=false
    keyTab="file:///C:/Temp/krbtest/meona-service.keytab" 
    principal=meona-service;
};

我想你复制,我很高兴给键标签文件,以及。它是在PDC上使用"kpass/out keytab/princ"生产的meona-service@meona.intra/通过/crypto AES256-SHA1/ptype KRB5_NT_PRINCIAL".

当LoginContext登录成功时,我认为密钥已成功恢复。

这是标准输出:

Java config name: null
Native config name: C:Windowskrb5.ini
Found KeyTab C:Tempkrbtestmeona-service.keytab for meona-service@meona.intra
Found KeyTab C:Tempkrbtestmeona-service.keytab for meona-service@meona.intra
Entered Krb5Context.acceptSecContext with state=STATE_NEW
>>> KeyTabInputStream, readName(): MEONA.INTRA
>>> KeyTabInputStream, readName(): meona-service
>>> KeyTab: load() entry length: 75; type: 18
Looking for keys for: meona-service@meona.intra
Added key: 18version: 1
>>> EType: sun.security.krb5.internal.crypto.Aes256CtsHmacSha1EType
Exception in thread "main" GSSException: Failure unspecified at GSS-API level (Mechanism level: Checksum failed)
    at sun.security.jgss.krb5.Krb5Context.acceptSecContext(Krb5Context.java:856)

如果我不使用keytab,而是使用预验证,我可以恢复密钥,但稍后会出现相同的错误。

有什么想法吗?

这是我用来生成SPNEGO协商标头的krb5.conf。

[libdefaults]
    default_tkt_enctypes = aes256-cts-hmac-sha1-96 aes128-cts rc4-hmac des3-cbc-sha1 des-cbc-md5 des-cbc-crc
    default_tgs_enctypes = aes256-cts-hmac-sha1-96 aes128-cts rc4-hmac des3-cbc-sha1 des-cbc-md5 des-cbc-crc
    permitted_enctypes   = aes256-cts-hmac-sha1-96 aes128-cts rc4-hmac des3-cbc-sha1 des-cbc-md5 des-cbc-crc
    default_realm = MEONA.INTRA
[realms]
    MEONA.INTRA = {
        kdc = pdc.meona.intra
        default_domain = MEONA.INTRA
}
[domain_realm]
    .MEONA.INTRA = MEONA.INTRA 

我尝试了不同的变体(有/没有".intera",大写/小写),但没有成功但是在将票证加密(使用AD服务用户的设置)更改为ARC4/HMAC1之后,一切都如预期的那样工作-AES256有什么问题

我在使用Java 17和Spnego 时看到了这个问题

我的Keytab文件包含AES128/256的条目。我们已通过支持为AD帐户启用AES令牌。然后我看到一个错误";校验和失败";(KVN和密码未更改)。支持通过ktpass生成keytab。我在服务器上更换了它,重新启动应用程序后,错误得到了解决。

我通过ktab重新生成了keytab文件,并使用了新的kvn-keytab。

在启用AES之后;刷新";AD中用于更改KVN参数的帐户。然后集成就会起作用。

最新更新