我们必须使用Java中的Apache CXF创建Web服务客户端。问题是我似乎无法使SSL会话正确参与。要么它完全失败,服务器无法解密一旦传输应用程序数据就发送给它的内容,或者我无法从服务器读取响应。
然而,当使用.NET内置的简单soap测试客户端尝试相同的事务时,一切都运行顺利。
服务器正在使用双重身份验证。
所有内容都是基于证书的(x509)存储在Windows证书库中(windows-MY和windows-ROOT)
编辑 是的,双重身份验证确实是客户端和服务器身份验证。
到目前为止,使用bountyCastle提供程序而不是SunMSCAPI似乎更进一步,但仍然无法使客户端身份验证工作。
客户端CXF 2.2.9的平台,Sun JDK 1.6_21 服务器IIS 6 ASP.NET不幸是我可以收集的,我无法控制服务器,必须按原样使用它。
更新 我现在正在使用JKS密钥库但仍然遇到问题。似乎客户端没有将其证书作为身份验证过程的一部分发送到服务器。结果我从服务器收到403.7错误。
有趣的是,我收到此错误消息为HTML页面,在可读之前必须先解密!
答案 0 :(得分:4)
据推测,通过双重身份验证,您的意思是除了服务器证书身份验证(更常见)之外,您还在使用客户端证书身份验证。
了解两侧使用哪些版本的平台以及应用了哪些补丁会很有用。
有些问题可能来自重新协商修复CVE-2009-3555(或缺少修复)。
问题是TLS中重新协商的初始设计中的缺陷,这是用于重新协商客户证书的内容。获取客户端证书有两种方法:服务器在初始TLS握手期间要求它,或者在后续握手期间请求它(例如,一旦它弄清楚请求的目的是什么和/或当试图访问某个禁区时)。第二种方法是重新谈判。不幸的是,在这方面TLS协议的设计存在安全漏洞,由于RFC 5746中描述的TLS扩展,该漏洞已经修复。
当最初披露这个漏洞时(2009年11月左右),一些平台和库(如Sun Java或OpenSSL)推出了一个快速修复程序,它只是禁止任何重新协商(因此只有客户端证书的初始协商才有效) 。稍后,一旦编写了RFC 5746,这些库就开始推出支持此扩展的实现。
据我所知,Microsoft在IIS及其Web框架中的默认设置是使用重新协商而不是初始协商。此外,它没有推出初始修复以禁用重新协商(有效地保持已知漏洞)。它最近才推出了一个补丁(默认情况下仍然容忍旧的实现):Microsoft Security Bulletin MS10-049 - Critical。
此微软安全博客上还有一个问题的解释: http://blogs.technet.com/b/srd/archive/2010/08/10/ms10-049-an-inside-look-at-cve-2009-3555-the-tls-renegotiation-vulnerability.aspx
基本上,如果你试图与只支持旧协商风格的服务器进行对话,而该服务器只有新的重新协商风格或根本没有重新协商,那么它就不会起作用。
如果您的服务器使用IIS或类似环境运行,您可以使用netsh
及其clientcertnegotiation=enable
选项启用初始客户端证书协商。
答案 1 :(得分:3)
Java不依赖于OS证书存储,需要使用自己的。
这将导入您的自签名证书。
cd JAVA_HOME/jre/lib/security
keytool -import -file server_cert.cer -keystore cacerts
答案 2 :(得分:0)
我发布这个作为答案虽然我意识到现在问题没有正确制定,因为我被抛入循环,因为我的.NET示例实际上是在执行黑客来解决问题。
正确的问题应该是
如何让Java在不要求提供证书的服务器上执行客户端身份验证?
答案实际上是在我们的鼻子底下,但要得到答案,需要正确的问题!!
非常感谢Bruno提供了一些非常有用的信息。
解决方案几乎可以归结为这两个问题:
Java HTTPS client certificate authentication
Client SSL authentication causing 403.7 error from IIS
虽然客户端“不应该”发送证书但是没有被问到我发现通过调整密钥库中的客户端证书来包含以下内容:
将所有这些推送到同一个证书库并将其用作密钥库。然后再次加载认证链作为信任存储。从那里它应该工作。据说这仍然存在失败的可能性。解决此特定问题的最安全方法是让服务器通过提供已接受的CA列表来主动向客户端请求身份验证证书。
希望这可以帮助其他任何可能陷入同样问题的人,在我到达邪恶的根源之前,肯定会让我旋转一段时间。