Java 对接 Active Directory 认证时,出现了认证不匹配的问题?

12

我有一些代码需要测试以确保它可以很好地进行身份验证。对于普通的Kerberos身份验证,它可以正常工作,因此我认为在与AD集成时只会出现一些小问题。不幸的是,我无法解决KrbException: KDC has no support for encryption type (14)。

我知道这个错误是由加密类型不匹配引起的。但我可以成功地使用kinit,只有在我的代码中才会遇到问题。我没有设置任何内容,所以我认为它应该继承与kinit相同的默认设置,但显然情况并非如此。

这是我的代码-

System.setProperty("sun.security.krb5.debug", "true");
System.setProperty("java.security.krb5.realm", "TEST.SQRRL.COM");
System.setProperty("java.security.krb5.kdc", "172.16.101.128");
System.setProperty("java.security.auth.login.config", "./conf/jaas.conf");
System.setProperty("javax.security.auth.useSubjectCredsOnly", "true");

// "Client" references the JAAS configuration in the jaas.conf file.
LoginContext loginCtx = null;
loginCtx = new LoginContext("Server", new LoginCallbackHandler("test".toCharArray()));
loginCtx.login();
subject = loginCtx.getSubject();

还有jaas.conf文件

Server {
com.sun.security.auth.module.Krb5LoginModule required
useKeyTab=false
storeKey=true
useTicketCache=true
principal="accumulo@test.SQRRL.COM";
};

而且,堆栈跟踪 -

>>>KRBError:
     sTime is Tue Nov 27 18:16:36 EST 2012 1354058196000
     suSec is 257213
     error code is 14
     error Message is KDC has no support for encryption type
     realm is test.SQRRL.COM
     sname is krbtgt/test.SQRRL.COM
     msgType is 30
javax.security.auth.login.LoginException: KDC has no support for encryption type (14)
    at com.sun.security.auth.module.Krb5LoginModule.attemptAuthentication(Krb5LoginModule.java:696)
    at com.sun.security.auth.module.Krb5LoginModule.login(Krb5LoginModule.java:542)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at javax.security.auth.login.LoginContext.invoke(LoginContext.java:769)
    at javax.security.auth.login.LoginContext.access$000(LoginContext.java:186)
    at javax.security.auth.login.LoginContext$4.run(LoginContext.java:683)
    at java.security.AccessController.doPrivileged(Native Method)
    at javax.security.auth.login.LoginContext.invokePriv(LoginContext.java:680)
    at javax.security.auth.login.LoginContext.login(LoginContext.java:579)
    at authenticators.KerberosAuthenticator.<init>(KerberosAuthenticator.java:37)
    at main.ServerImpl.<init>(ServerImpl.java:91)
    at main.PlugServer.run(PlugServer.java:22)
    at main.PlugServer.main(PlugServer.java:42)
Caused by: KrbException: KDC has no support for encryption type (14)
    at sun.security.krb5.KrbAsRep.<init>(KrbAsRep.java:66)
    at sun.security.krb5.KrbAsReq.getReply(KrbAsReq.java:446)
    at sun.security.krb5.Credentials.sendASRequest(Credentials.java:401)
    at sun.security.krb5.Credentials.acquireTGT(Credentials.java:373)
    at com.sun.security.auth.module.Krb5LoginModule.attemptAuthentication(Krb5LoginModule.java:662)
    ... 15 more
Caused by: KrbException: Identifier doesn't match expected value (906)
    at sun.security.krb5.internal.KDCRep.init(KDCRep.java:133)
    at sun.security.krb5.internal.ASRep.init(ASRep.java:58)
    at sun.security.krb5.internal.ASRep.<init>(ASRep.java:53)
    at sun.security.krb5.KrbAsRep.<init>(KrbAsRep.java:50)
    ... 19 more
Exception in thread "main" java.lang.RuntimeException: javax.security.auth.login.LoginException: KDC has no support for encryption type (14)
    at main.PlugServer.run(PlugServer.java:36)
    at main.PlugServer.main(PlugServer.java:42)
Caused by: javax.security.auth.login.LoginException: KDC has no support for encryption type (14)
    at com.sun.security.auth.module.Krb5LoginModule.attemptAuthentication(Krb5LoginModule.java:696)
    at com.sun.security.auth.module.Krb5LoginModule.login(Krb5LoginModule.java:542)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at javax.security.auth.login.LoginContext.invoke(LoginContext.java:769)
    at javax.security.auth.login.LoginContext.access$000(LoginContext.java:186)
    at javax.security.auth.login.LoginContext$4.run(LoginContext.java:683)
    at java.security.AccessController.doPrivileged(Native Method)
    at javax.security.auth.login.LoginContext.invokePriv(LoginContext.java:680)
    at javax.security.auth.login.LoginContext.login(LoginContext.java:579)
    at authenticators.KerberosAuthenticator.<init>(KerberosAuthenticator.java:37)
    at main.ServerImpl.<init>(ServerImpl.java:91)
    at main.PlugServer.run(PlugServer.java:22)
    ... 1 more
Caused by: KrbException: KDC has no support for encryption type (14)
    at sun.security.krb5.KrbAsRep.<init>(KrbAsRep.java:66)
    at sun.security.krb5.KrbAsReq.getReply(KrbAsReq.java:446)
    at sun.security.krb5.Credentials.sendASRequest(Credentials.java:401)
    at sun.security.krb5.Credentials.acquireTGT(Credentials.java:373)
    at com.sun.security.auth.module.Krb5LoginModule.attemptAuthentication(Krb5LoginModule.java:662)
    ... 15 more
Caused by: KrbException: Identifier doesn't match expected value (906)
    at sun.security.krb5.internal.KDCRep.init(KDCRep.java:133)
    at sun.security.krb5.internal.ASRep.init(ASRep.java:58)
    at sun.security.krb5.internal.ASRep.<init>(ASRep.java:53)
    at sun.security.krb5.KrbAsRep.<init>(KrbAsRep.java:50)
    ... 19 more
3个回答

11

所以,我已经解决了这个问题。我只能猜测 Windows Server 2012 中的 Active Directory 对 DES 的支持出了问题,因为我不得不调整我的 krb5.conf 文件并将两种默认票证类型和允许的类型设置为只有 aes256-cts-hmac-sha1-96 才能让一个用户使用。在启用其他用户的 AES256 后,它继续工作。


请问您能否提供一份您的 krb5.conf 的示例呢? - undefined
不行,这是十多年前的事了。 - undefined

3

您需要访问用户帐户并勾选“使用Kerberos DES加密类型”复选框。

当然,您需要作为管理员登录到您的DS才能执行此操作。


1
我已经勾选了那些框并尝试重置用户密码,但没有成功。这是在Windows Server 2012上的Active Directory。 - ohshazbot

1

看一下 KDCRep.java 中的{{code>init()}},唯一可能会导致错误的部分是:

    150           if ((subDer.getTag() & 0x1F) == 0x00) {
    151               pvno = subDer.getData().getBigInteger().intValue();
    152               if (pvno != Krb5.PVNO) {
    153                   throw new KrbApErrException(Krb5.KRB_AP_ERR_BADVERSION);
    154               }
    155           } else {
    156               throw new Asn1Exception(Krb5.ASN1_BAD_ID);
    157           }

看起来有点奇怪,错误被打印为KrbException,但是它可能有效,因为KrbApErrExceptionKrbException的子类。 init()不能抛出任何其他KrbException的子类。

算了吧。更好的可能性是其中一个Asn1Exception,因为KrbAsRep.java中的构造函数捕获并重新抛出这些错误作为KrbException(具有与堆栈跟踪相当匹配的适当initCause)。

"标识符与预期值不匹配 (906)" 让我觉得它会抛出一个 Asn1Exception(Krb5.ASN1_BAD_ID)因为Krb5.ASN1_BAD_ID的值为906。这并没有太多帮助,因为似乎在 init() 中是默认错误。

看看是否可以生成与您的配置对应的 DerValue 并手动检查它,在那里查看 init() 是否会拒绝它,然后从那里向后退,查看您的配置的哪个部分创建了错误位。


经过进一步检查,信息“KDC不支持加密类型”的消息让我相信Krb5.KDC_ERR_ETYPE_NOSUPP可能已被使用。但是,由于它仅适用于Etype的默认实例,这可能意义不大。

1
“标识符与预期值不匹配(906)”是Kerberos GSSAPI实现的低层中的标准异常。它会因为很多事情而被抛出,但在它上面的层次中有适当的错误处理。我相当有信心认为服务器和Java客户端之间存在某种加密不匹配,这是从KDC的消息中得出的。我卡在如何在Java客户端中设置不同的加密类型上。系统的配置没问题,因为kinit可以工作。问题在于Java的设置有问题,我不知道该怎么解决。(我想) - ohshazbot

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接