HttpClient 4.1 出现 SSL“Peer Not Authenticated”错误

Posted

技术标签:

【中文标题】HttpClient 4.1 出现 SSL“Peer Not Authenticated”错误【英文标题】:SSL "Peer Not Authenticated" error with HttpClient 4.1 【发布时间】:2012-07-31 23:16:55 【问题描述】:

我正在构建一个简单的应用程序监视器来轮询我们的一个 API URL,如果它无法从响应中获取 HTTP 200 状态代码(这表明我们的 API 由于某种原因而关闭),则向我们发送电子邮件。

我正在使用 HttpClient 4.1(这很重要,因为它的 API 与 3.x 大不相同)。

我们的 API 使用 SSL 是安全的,但是输入:

http://example.com/our-api

进入网络浏览器会将您重定向到

https://example.com/our-api

不会导致任何错误。

当 HttpClient 尝试访问此 URL (http://example.com/our-api) 时,它会失败并出现 javax.net.ssl.SSLPeerUnverifiedException 异常并显示以下消息:

对等体未通过身份验证

我看到其他人经常发生这种情况,this 帖子证明了这一点(它还提供了一些规避此问题的方法 - 实际上我今晚将尝试实施的解决方案)。

这篇其他帖子(以及其他类似的帖子)没有首先解释为什么会发生这种情况!所以,与其问“我该如何解决这个问题?”我想我会问“为什么会发生这种情况?”在我继续提出建议的解决方案之一之前,我想知道我正在尝试解决的问题是什么;- )

【问题讨论】:

你能发布完整的堆栈跟踪吗? 需要注意的是,这个消息一定是由于HttpClient中的奇怪编程造成的。之前会有一个 SSLException 'handshake failure',这就是应该抛出的。显然继续执行 SSLSession.getPeerCertificate() 调用,这是标题中唯一引发异常的 API。 【参考方案1】:

如果服务器的证书是自签名的,那么这是按设计工作的,您必须将服务器的证书导入您的密钥库。

假设服务器证书由知名 CA 签名,这是因为现代浏览器可用的 CA 证书集远大于 JDK/JRE 附带的有限集。

您提到的其中一篇文章中给出的 EasySSL 解决方案只是掩盖了错误,您将不知道服务器是否具有有效的证书。

您必须将正确的根 CA 导入您的密钥库以验证证书。使用现有的 SSL 代码无法解决这个问题是有原因的,这是为了防止您编写表现得好像它们是安全的但实际上并不安全的程序。

【讨论】:

大多数情况下,SSL 服务器会将链向上发送到但不包括根证书。所以大多数时候您不必将整个链导入密钥库。但是,您应该明确信任根证书。 @owlstead 是的,通常您只需要导入根 CA;答案已编辑。 我将证书(base64 版本)导入到lib\security\cacerts 下的密钥库中,但 java 仍然给出相同的错误。当我将它导入 Windows 受信任的证书存储时,chrome 停止给出错误。但是当我使用 java keytool 时,它仍然无法连接。 如果服务器只使用 AES_256 密码套件,那么客户端应该有 JCE Unlimited Strength Jurisdiction Policy Files【参考方案2】:

这是在

时抛出的

... 对等方无法识别自己(例如;没有 证书,正在使用的特定密码套件不支持 身份验证,或 SSL 期间未建立对等身份验证 握手)抛出此异常。

这个异常的可能原因(堆栈跟踪在哪里)会告诉你为什么抛出这个异常。 Java 附带的默认密钥库很可能不包含(并且不信任)正在使用的 TTP 的根证书。

答案是检索根证书(例如,从您的浏览器 SSL 连接中),将其导入 cacerts 文件并使用 Java JDK 提供的 keytool 信任它。否则,您将不得不以编程方式分配另一个信任库。

【讨论】:

【参考方案3】:
keytool -import -v -alias cacerts -keystore cacerts.jks -storepass changeit -file C:\cacerts.cer

【讨论】:

【参考方案4】:

我不是 Java 开发人员,但正在使用 Java 应用程序来测试 RESTful API。为了让我修复错误,我必须在网络服务器中安装中间证书以使错误消失。我使用的是 lighttpd,原始证书安装在 IIS 服务器上。希望能帮助到你。这些是我在服务器上丢失的证书。

CA.crt UTNAddTrustServer_CA.crt AddTrustExternalCARoot.crt

【讨论】:

以上是关于HttpClient 4.1 出现 SSL“Peer Not Authenticated”错误的主要内容,如果未能解决你的问题,请参考以下文章

java 11 HttpClient 导致无休止的 SSL 循环

使用 HttpClient 允许不受信任的 SSL 证书

C# HttpClient 是不是忽略 SSL 证书错误?

如何在 Apache HttpClient 4.1 中处理会话

使用 HttpClient 在 Android 中重用 SSL 会话

同时使用 SSL 加密和 NTLM 身份验证的 HttpClient 失败