Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/385.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ssl/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
我得到了javax.net.ssl.SSLPeerUnverifiedException:在我的JUnit测试中没有对对等点进行身份验证_Java_Ssl_Junit - Fatal编程技术网

我得到了javax.net.ssl.SSLPeerUnverifiedException:在我的JUnit测试中没有对对等点进行身份验证

我得到了javax.net.ssl.SSLPeerUnverifiedException:在我的JUnit测试中没有对对等点进行身份验证,java,ssl,junit,Java,Ssl,Junit,我正在为一个使用RESTAPI的应用程序创建一些单元测试。当我尝试向服务器URL发送HttpPost请求时(https://some.server.com),我得到了这个: javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated at com.sun.net.ssl.internal.ssl.SSLSessionImpl.getPeerCertificates(SSLSessionImpl.java:352)

我正在为一个使用RESTAPI的应用程序创建一些单元测试。当我尝试向服务器URL发送HttpPost请求时(https://some.server.com),我得到了这个:

javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated
    at com.sun.net.ssl.internal.ssl.SSLSessionImpl.getPeerCertificates(SSLSessionImpl.java:352)
    at org.apache.http.conn.ssl.AbstractVerifier.verify(AbstractVerifier.java:128)
    at org.apache.http.conn.ssl.SSLSocketFactory.createSocket(SSLSocketFactory.java:399)
    at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:143)
    at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:149)
    at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:108)
    at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:415)
    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:641)
    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:576)
    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:554)
服务器具有已验证的HTTPS证书。而且,当我在生产环境中运行这个程序时,它工作得很好。所以我认为这与JUnit和/或我的本地计算机有关

我还使用了一个由以下内容创建的HttpClient:

public static class WebClientDevWrapper {
    public static HttpClient wrapClient(HttpClient base) {
        try {
            SSLContext ctx = SSLContext.getInstance("TLS");
            X509TrustManager tm = new X509TrustManager() {

                public void checkClientTrusted(X509Certificate[] xcs, String string) throws CertificateException {
                }

                public void checkServerTrusted(X509Certificate[] xcs, String string) throws CertificateException {
                }

                public X509Certificate[] getAcceptedIssuers() {
                    return null;
                }
            };
            ctx.init(null, new TrustManager[]{tm}, null);
            SSLSocketFactory ssf = new SSLSocketFactory(ctx);
            ssf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
            ClientConnectionManager ccm = base.getConnectionManager();
            SchemeRegistry sr = ccm.getSchemeRegistry();
            sr.register(new Scheme("https", ssf, 443));
            return new DefaultHttpClient(ccm, base.getParams());
        } catch (Exception ex) {
            ex.printStackTrace();
            return null;
        }
    }
}
好的,如果我用上面的代码创建一个HTTPClient,它应该避免SSLPeerUnverifiedException,但它似乎不起作用


那么我该如何解决这个问题呢?我尝试了更多的方法来创建不会抱怨SSL证书的HttpClient,但到目前为止还没有任何效果。

您是否正在使用Linux?我在Ubuntu系统上使用Java和SSL时遇到了疯狂的问题。它与/etc/hosts文件有关,该文件将localhost映射到127.0.1.1,而不是127.0.0.1。根据IANA映射,这两种方法同样有效,但如果Java不是127.0.0.1,它似乎会被忽略。当问题出现时,它甚至很少通过握手,因此即使您完全禁用了所有证书检查,它仍然会以意外的方式失败

如果我用上面的代码创建一个HTTPClient,它应该避免 SSLPeerUnverifiedException


一点也不。不安全的X509TrustManager所做的只是接受任何对等证书,无论其是否可信,这完全是毫无意义的。您看到的是,对等方根本没有发送证书。

对这个问题的大多数回答(包括StackOverflow和其他方面)花费了太多时间关注Java代码本身,通常给出的答案是绕过所有主机的SSL验证。请仅将此作为绝对的最后手段,即使它只是一个开发环境,并且仅在必要时按每个域执行,而不是全面执行。这是一种糟糕的做法,我想知道“仅限于开发环境”的代码将其投入生产的频率有多高

事实上,误差是完全准确的,在某些情况下,实际上还有更好的选择。只有在以下情况下,才会出现此错误:

  • 您要连接的主机上没有安装SSL证书
  • 证书已安装,但无效。这可能是因为它已过期,或者CN与安装证书的主机域不匹配
  • 证书有效,但Java JDK实现无法识别证书颁发机构(CA)。如果Java JDK实现无法识别证书“信任链”中的一个机构,那么您可能会收到javax.net.ssl.SSLHandshakeException
  • 证书是自签名的,这实际上与上面相同,因为自签名者不是可识别的CA
第一个要点有自己的一系列问题。在任何生产场景中,当没有安装证书,但应用程序仍然通过HTTPs提供流量服务时,为什么要连接到主机,这一点值得怀疑。如果您通过该连接发送敏感用户数据,那么您已经创建了一个严重的安全漏洞。这一要点的唯一解决方案是绕过验证,除非你只是简单地“爬行”或“抓取”内容,否则这根本不是解决方案

不幸的是,第二个要点也是如此。如果必须通过SSL连接到主机,唯一的解决方案是绕过SSL验证。当证书过期或使用无效CN创建时,即使将证书添加到信任库也无法防止此异常。如果您与主持人有持续的关系,请询问他们是否可以解决问题

第三个和第四个要点的解决方案取决于您与要连接的主机建立的信任级别,但这比简单地绕过所有SSL主机验证要好得多。只需将证书添加为受信任的证书(授权)

首先,使用您喜爱的浏览器下载证书。Firefox和Chrome都提供了下载域证书的实用程序。在Java JDK中,CA信任库位于[Java_HOME]/jre/lib/security/cacerts。使用以下keytool命令将下载的证书添加到其中:

keytool -import -trustcacerts -alias domainalias -file host.crt -keystore cacerts
有关更多信息和其他keytool命令,我想使用以下页面:


以下是针对我的上下文的解决方案

我在公司环境中的Windows7上工作,这意味着我有代理。 SOAP url位于测试环境中,该公司代理未看到该环境

确保 文件->首选项您可以将代理设置设置设置为“无”


你好,卡洛。

这听起来不太对劲。SSL根本不关心本地IP地址。HTTPS有,就像它有主机名验证步骤一样。@EJP:不,SSL没有,但Java出于某种原因有。我从来没有深入研究过原因,但我在从Java建立SSL连接时遇到了重复的问题,在这里更改我描述的/etc/hosts条目会使它在没有其他变化的情况下工作或不工作?后者执行HTTPS主机名验证步骤。前者没有。@EJP:那不是HTTP连接。它发生在我试图在使用1.8.1版时启用SSL时。Ryan对/etc/hosts的观察让我找到了答案,尽管在我的例子中,映射到“localhost”的IP不是问题所在;本地计算机主机名的映射(在我的例子中是“dell desktop”)是个问题,它确实映射到了127.0.1.1。将其设置为127.0.0.1似乎可以消除SSLPeerUnverifiedException。这很有意义。。。我在
X509TrustManager
方法中添加了一些调试输出,它们似乎从未被调用过。相反,当我调用时,例如,这些方法是invoked@Cristian青年成就