SSL“对等体未通过身份验证"HttpClient 4.1 出错

2022-01-25 00:00:00 ssl ssl-certificate httpclient java

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

I am building a simple app monitor to poll one of our API URLs and email us if it can't get a HTTP 200 status code from the response (this would indicate our API is down for some reason).

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

I am using HttpClient 4.1 (this is important because its API differs greatly from 3.x).

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

Our API is secure with SSL, however entering:

http://example.com/our-api

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

into a web browser redirects you to

https://example.com/our-api

不会导致任何错误.

当 HttpClient 尝试访问此 URL (http://example.com/our-api) 时,它会因 javax.net.ssl.SSLPeerUnverifiedException 异常而失败带有一条消息说明:

When HttpClient attempts to hit this URL (http://example.com/our-api), it fails with a javax.net.ssl.SSLPeerUnverifiedException exception with a message stating:

对等体未通过身份验证

this 帖子(其中还提供了一些规避此问题的方法 - 实际上我今晚将尝试实施的解决方案.

I see this happening a lot for other people as is evidenced by this post (which also provides some ways of circumventing this problem - a solution that I am going to try and implement tonight in fact).

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

What this other post (and the other similar ones to it) do not do is explain why this is happening in the first place! So, rather than ask "how do I fix this?" I figured I would ask "why is this happening?" Before I go barging ahead with one of the proposed solutions, I'd like to know what the problem is that I'm attempting to fix ;-)

推荐答案

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

If the server's certificate is self-signed, then this is working as designed and you will have to import the server's certificate into your keystore.

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

Assuming the server certificate is signed by a well-known CA, this is happening because the set of CA certificates available to a modern browser is much larger than the limited set that is shipped with the JDK/JRE.

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

The EasySSL solution given in one of the posts you mention just buries the error, and you won't know if the server has a valid certificate.

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

You must import the proper Root CA into your keystore to validate the certificate. There's a reason you can't get around this with the stock SSL code, and that's to prevent you from writing programs that behave as if they are secure but are not.

相关文章