栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

Apache HTTPClient SSLPeerUnverifiedException

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Apache HTTPClient SSLPeerUnverifiedException

编辑 我知道这个答案很久以前就被接受了,并且也被投票了3次,但这是(至少部分是)错误的,所以这里有更多关于此异常的信息。不便之处敬请原谅。

javax.net.ssl.SSLPeerUnverifiedException:对等方未通过身份验证

当远程服务器根本不发送证书时, 通常会 抛出此异常。但是,由于在此版本

sun.security.ssl.SSLSocketImpl.getSession()
中实现的方式以及实现的方式,因此在使用Apache HTTP
Client时会遇到一些极端情况。

当使用Apache HTTP Client时,当不信任远程证书时也会抛出该异常,这通常会抛出“

sun.security.validator.ValidatorException: PKIX path building failed
”。

发生这种情况的原因是因为Apache HTTP Client

SSLSession
在执行其他操作之前会尝试获取和对等证书。

提醒一下,有3种方法可以通过发起握手

SSLSocket

  • 调用开始显式开始握手的startHandshake,或
  • 尝试在此套接字上读取或写入应用程序数据会导致隐式握手,或者
  • 如果当前没有有效的会话,则对getSession的调用尝试建立会话,并且隐式握手已完成。

这是3个示例,所有示例均针对具有不可信证书的主机(使用

javax.net.ssl.SSLSocketFactory
,而不是Apache)。

范例1:

    SSLSocketFactory ssf = (SSLSocketFactory) sslContext.getSocketFactory();    SSLSocket sslSocket = (SSLSocket) ssf.createSocket("untrusted.host.example", 443);    sslSocket.startHandshake();

这将引发“

javax.net.ssl.SSLHandshakeException:sun.security.validator.ValidatorException: PKIX path building failed
”(如预期)。

范例2:

    SSLSocketFactory ssf = (SSLSocketFactory) sslContext.getSocketFactory();    SSLSocket sslSocket = (SSLSocket) ssf.createSocket("untrusted.host.example", 443);    sslSocket.getInputStream().read();

这也会引发“

javax.net.ssl.SSLHandshakeException:sun.security.validator.ValidatorException: PKIX path building failed
”(如预期)。

范例3:

    SSLSocketFactory ssf = (SSLSocketFactory) sslContext.getSocketFactory();    SSLSocket sslSocket = (SSLSocket) ssf.createSocket("untrusted.host.example", 443);    SSLSession sslSession = sslSocket.getSession();    sslSession.getPeerCertificates();

但是,这引发了

javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated

这是Apache
HTTP客户端

AbstractVerifier
org.apache.http.conn.ssl.SSLSocketFactory
在4.2.1版中使用的逻辑。更高版本基于发出的HTTPCLIENT-1346报告显式调用
startHandshake()

最终,这似乎来自的实现

sun.security.ssl.SSLSocketImpl.getSession()
,该实现捕获了
IOException
在调用
startHandshake(false)
(内部方法)时抛出的潜在s
,而没有进一步抛出它。这可能是一个错误,尽管这不会对安全产生重大影响,因为
SSLSocket
无论如何仍将关闭。

范例4:

    SSLSocketFactory ssf = (SSLSocketFactory) sslContext.getSocketFactory();    SSLSocket sslSocket = (SSLSocket) ssf.createSocket("untrusted.host.example", 443);    SSLSession sslSession = sslSocket.getSession();    // sslSession.getPeerCertificates();    sslSocket.getInputStream().read();

值得庆幸的是,

javax.net.ssl.SSLHandshakeException:sun.security.validator.ValidatorException: PKIX path buildingfailed
每当您实际尝试使用它时,它仍然会抛出“ ”
SSLSocket
(在没有获得对等证书的情况下获得会话不会造成漏洞)。


如何解决这个问题

像其他任何不信任的证书问题一样,确保您使用的信任库包含必要的信任锚(例如,颁发要尝试验证的链的CA证书,或者可能是实际服务器)特殊情况证书)。

要解决此问题,您应该将CA证书(或者可能是服务器证书本身)导入到信任库中。你可以这样做:

  • 在您的JRE信任库中,通常是
    cacerts
    文件(不一定是最好的文件,因为这会影响使用该JRE的所有应用程序),
  • 在您的信任库的本地副本中(您可以使用
    -Djavax.net.ssl.trustStore=...
    选项进行配置),
  • 通过
    SSLContext
    为该连接创建一个特定对象。(有人建议使用不执行任何操作的信任管理器,但这会使您的连接容易受到MITM攻击。)

初步答案

javax.net.ssl.SSLPeerUnverifiedException:对等方未通过身份验证

这与信任证书无关,或者您必须创建一个自定义

SSLContext
:这是由于服务器根本不发送任何证书。

显然,该服务器未配置为正确支持TLS。这将失败(您将不会获得远程证书):

openssl s_client -tls1 -showcerts -connect

appserver.gtportalbase.com:443

但是,SSLv3似乎可以工作:

openssl s_client -ssl3 -showcerts -connect

appserver.gtportalbase.com:443

如果您知道谁在运行此服务器,则值得与他们联系以解决此问题。至少现在,服务器应该真正支持TLSv1。

同时,解决此问题的一种方法是创建您自己的问题并将

org.apache.http.conn.ssl.SSLSocketFactory
其用于与Apache
Http客户端的此连接。

该工厂需要创建一个

SSLSocket
照常使用的方法
sslSocket.setEnabledProtocols(new String[]{"SSLv3"});
,以在返回该套接字之前使用它来禁用TLS,否则默认情况下将启用它。



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/486089.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号