我正在进行一个项目,在这个项目中,我们使用JAAS/Krb5LoginModule和useTicketCache & doNotPrompt,以及更改http://support.microsoft.com/kb/308339注册表,以支持我们在域加入计算机的windows登录上的身份验证。
然后,我们使用jgss/ Kerberos 获取GSS令牌(rfc1964),用于在与服务通信时使用WSS令牌配置文件1.1.1保护SOAP消息。这涉及到将b64编码的GSS令牌包括在SOAP信封/标头的安全元素中,并使用客户机/服务sessionKey对元素的组件进行签名。
我们通过查询JAAS/Krb5LoginModule返回的javax.security.auth.Subject的私有凭据来获取client/sessionKey,并查找与服务对等名匹配的javax.security.auth.kerberos.KerberosTicket并调用其getSessionKey()。
所有这些在Java-6中都很好,但是Java-7客户端失败了,因为Java7创建的Kerberos KRB_AP_REQ消息似乎发生了变化。Java-7 KRB_AP_REQ身份验证器包含一个与sessionKey不同的子密钥.由于Kerberos规范(请参阅下面的摘录)指出,这个子键取代了sessionKey,那么我们使用sessionKey进行签名的Java6行为就不再正确了。
RFC1510 - Kerberos网络认证服务(V5) 5.3.2.认证器 子密钥此字段包含客户端对用于保护此特定应用程序会话的加密密钥的选择。除非应用程序另有规定,否则如果将此字段排除在外,将使用票证中的会话密钥。
我没有看到任何地方记录了这种更改,但至少在Java(TM) SE运行时环境(Build1.7.0_11-B21)中证实了这种行为。
在这一点上,除非我遗漏了一些显而易见的东西(我也希望我错过了),否则我们的选择似乎是:
对这些或其他可能的选择有什么建议或见解吗?
发布于 2013-08-20 14:58:47
在Java1.7中使用JGSS获取客户端会话密钥时,我们也会遇到这个问题。显然,在Java1.6中,子密钥总是从会话密钥中克隆出来的,请参见sun.security.krb5.EncryptionKey构造函数:
EncryptionKey(EncryptionKey encryptionkey)
throws KrbCryptoException
{
keyValue = (byte[])(byte[])encryptionkey.keyValue.clone();
keyType = encryptionkey.keyType;
}从1.7.0_b07开始,这个构造函数利用java.security.SecureRandom生成一个新的子键。我认为这是作为JDK-4460771 : Kerberos应该能够生成子会话密钥。的一部分完成的。com.sun.security.jgss.ExtendedGSSContext似乎提供了从现在开始(在Sun上)访问子项的“标准”方法,所以我想如果这个类是可用的,我们应该使用它(在底层JVM上),请参见:
JDK-6710360 :将Kerberos会话密钥导出到应用程序
谢谢,Detelin
发布于 2013-07-27 06:34:16
我在ExtendedGSSContext.inquireSecContext() doc中没有看到任何指示它返回子键(如果存在于KRB5_GET_SESSION_KEY中)的东西;您从其他源知道它返回子键吗?
在任何情况下,您都需要使用子项。我会这样看待它:您最初的实现是不正确的,因为WSS Kerberos文档明确指出,如果存在,将使用子键。因为Java 6 Kerberos库没有生成子键,所以它刚好工作。既然有一个出现了,你的错误就暴露了,你必须修复它。
我不熟悉WSS,但文档似乎表明您可以为令牌选择各种编码,其中之一是直接使用GSSAPI而不是Kerberos AP-REQ。也许如果你一开始就使用了GSSAPI,它会让你免受这种变化的影响--也许现在切换到GSSAPI将是最简单的解决方法。
https://stackoverflow.com/questions/17830318
复制相似问题