我得到了javax.net.ssl.SSLPeerUnverifiedException:在我的JUnit测试中没有对对等点进行身份验证
我正在为一个使用RESTAPI的应用程序创建一些单元测试。当我尝试向服务器URL发送HttpPost请求时(https://some.server.com),我得到了这个:我得到了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)
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
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青年成就