我正在开发一个项目,我们将 JAAS/Krb5LoginModule 与useTicketCache和doNotPrompt以及allowtgtsessionkey注册表更改一起使用,以在加入域的计算机的 Windows 登录上搭载我们的身份验证。
然后,我们使用 jgss /kerberos获取GSS API Kerberos 令牌 (rfc1964) ,在与服务通信时,我们使用WSS Kerberos 令牌配置文件 1.1.1来保护 SOAP 消息。这包括在 SOAP Envelope/Header 的 Security 元素中包含 b64 编码的 GSS 令牌,并使用客户端/服务 sessionKey 对元素的组件进行签名。
我们通过查询 JAAS/Krb5LoginModule 返回的 javax.security.auth.Subject 的私有凭据并查找与我们的服务对等名称匹配的 javax.security.auth.kerberos.KerberosTicket 并调用其 getSessionKey 来获取客户端/会话密钥()。
所有这些在 Java-6 中都可以正常工作,但是 Java-7 客户端失败了,因为 Java-7 创建的 Kerberos KRB_AP_REQ 消息似乎发生了变化。Java-7 KRB_AP_REQ Authenticator 包含一个与sessionKey不同的子密钥。由于 Kerberos 规范(请参阅下面的摘录)说此子密钥取代了 sessionKey,因此我们使用 sessionKey 进行签名的 Java-6 行为不再正确。
RFC1510 - Kerberos 网络身份验证服务 (V5)
5.3.2. 身份验证器
subkey This field contains the client's choice for an encryption key which is to be used to protect this specific application session. Unless an application specifies otherwise, if this field is left out the session key from the ticket will be used.
我没有看到任何记录此更改的地方,但至少在 Java(TM) SE 运行时环境(内部版本 1.7.0_11-b21)中确认了该行为。
在这一点上,除非我错过了一些明显的东西(我希望我有),我们的选择似乎是:
更改 Java-7 Kerberos 配置以恢复到 Java-6 行为 - 不幸的是,我在文档中没有看到任何似乎表明这是可能的内容。
找到访问子项的方法。对于我探索的这个选项是
一个。解码 b64 编码的 GSS Token,取出加密的 Authenticator,使用 sessionKey 解密,解码 ASN.1 DER 编码并取出子密钥。
湾。使用看似非标准的GSS API 扩展,并使用带有 KRB5_GET_SESSION_KEY的ExtendedGSSContext.inquireSecContext()方法来获取子密钥。
对这些或其他可能的选项有任何建议/见解吗?