例外:javax.net.ssl.SSLPeerUnverifiedException:peer未经过身份验证

时间:2012-03-06 04:58:18

标签: java apache-httpclient-4.x

public HttpClientVM() {

    BasicHttpParams params = new BasicHttpParams();
    ConnManagerParams.setMaxTotalConnections(params, 10);
    HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
    HttpProtocolParams.setUseExpectContinue(params, false);
    HttpConnectionParams.setStaleCheckingEnabled(params, true);
    HttpConnectionParams.setConnectionTimeout(params, 30000);
    HostnameVerifier hostnameVerifier=
          org.apache.http.conn.ssl.SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER;
    HttpsURLConnection.setDefaultHostnameVerifier(hostnameVerifier);
    SSLSocketFactory socketFactory = SSLSocketFactory.getSocketFactory();
    socketFactory.setHostnameVerifier((X509HostnameVerifier) hostnameVerifier);
    SchemeRegistry schemeRegistry = new SchemeRegistry();
    schemeRegistry.register(new Scheme("http",socketFactory, 80));
    schemeRegistry.register(new Scheme("https",socketFactory, 443));
        ThreadSafeClientConnManager manager = new ThreadSafeClientConnManager(params, schemeRegistry);
        // Set verifier     
        client = new DefaultHttpClient(manager, params);    
    }

问题:

执行client.accessURL(url)时,会发生以下错误:

Exception in thread "main" 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.connectSocket(SSLSocketFactory.java:397)
    at org.apache.http.conn.ssl.SSLSocketFactory.connectSocket(SSLSocketFactory.java:495)
    at org.apache.http.conn.scheme.SchemeSocketFactoryAdaptor.connectSocket(SchemeSocketFactoryAdaptor.java:62)
    at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:148)
    at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:150)
    at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:121)
    at org.apache.http.impl.client.DefaultRequestDirector.tryConnect(DefaultRequestDirector.java:575)
    at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:425)
    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:820)
    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:754)
    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:732)

其他信息:

  • Window 7
  • HttpClient 4

8 个答案:

答案 0 :(得分:23)

过期的证书是我们“javax.net.ssl.SSLPeerUnverifiedException:peer not authenticated”的原因。

  

keytool -list -v -keystore filetruststore.ts

    Enter keystore password:
    Keystore type: JKS
    Keystore provider: SUN
    Your keystore contains 1 entry
    Alias name: somealias
    Creation date: Jul 26, 2012
    Entry type: PrivateKeyEntry
    Certificate chain length: 1
    Certificate[1]:
    Owner: CN=Unknown, OU=SomeOU, O="Some Company, Inc.", L=SomeCity, ST=GA, C=US
    Issuer: CN=Unknown, OU=SomeOU, O=Some Company, Inc.", L=SomeCity, ST=GA, C=US
    Serial number: 5011a47b
    Valid from: Thu Jul 26 16:11:39 EDT 2012 until: Wed Oct 24 16:11:39 EDT 2012

答案 1 :(得分:13)

此错误是因为您的服务器没有有效的SSL证书。因此,我们需要告诉客户端使用不同的TrustManager。以下是示例代码:

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,SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
ClientConnectionManager ccm = base.getConnectionManager();
SchemeRegistry sr = ccm.getSchemeRegistry();
sr.register(new Scheme("https", 443, ssf));

client = new DefaultHttpClient(ccm, base.getParams());

答案 2 :(得分:12)

如果您的服务器基于JDK 7并且您的客户端位于JDK 6上并使用SSL证书,则会出现此异常。在JDK 7中,sslv2hello消息握手默认禁用,而在JDK 6中,sslv2hello消息握手已启用。因此,当您的客户端尝试连接服务器时,将向服务器发送sslv2hello消息,并且由于sslv2hello消息禁用,您将收到此异常。要解决此问题,您必须将客户端移至JDK 7,或者必须使用6u91版本的JDK。但要获得此版本的JDK,您必须获得MOS(My Oracle Support)Enterprise支持。这个补丁不公开。

答案 3 :(得分:5)

如果客户端指定“https”但服务器只运行“http”,则可以获取此信息。因此,服务器不希望建立安全连接。

答案 4 :(得分:3)

如果您尝试通过HTTPS连接并且服务器未配置为正确处理SSL连接,也会发生这种情况。

我会检查您的应用程序服务器SSL设置,并确保正确配置了认证。

答案 5 :(得分:0)

在我的情况下,我使用的是JDK 8客户端,服务器使用的是不安全的旧密码。服务器是Apache,我将此行添加到Apache配置:

SSLCipherSuite ALL:!ADH:RC4+RSA:+HIGH:!MEDIUM:!LOW:!SSLv2:!EXPORT

您应该使用这样的工具来验证您的SSL配置目前是否安全:https://www.ssllabs.com/ssltest/analyze.html

答案 6 :(得分:0)

在我的例子中,服务器在 Docker 上运行(使用基础镜像 takeopenjdk/openjdk11:alpine),问题是 TLS 协议级别错误(感谢以下页面提供解释:https://jfrog.com/knowledge-base/how-to-resolve-the-javax-net-ssl-sslpeerunverifiedexception-peer-not-authenticated-error-when-using-java-11/)。

最终的解决方案是使用以下 java 标志运行客户端:

-Djdk.tls.client.protocols=TLSv1.2

答案 7 :(得分:-7)

如果您处于开发模式且证书无效,为什么不设置 weClient.setUseInsecureSSL(true) 。适合我

相关问题