2012-03-06 208 views
28
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);  
    } 

Window7的,HttpClient4异常:javax.net.ssl.SSLPeerUnverifiedException:同行未被认证

在执行时: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) 

回答

8

此错误是因为您的服务器没有有效的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()); 
+5

如何从这一端删除安全措施来解决另一端的问题?该TrustManager代码甚至不符合规范。 – EJP 2012-03-06 05:30:25

+0

我没有看到你的观点。问题来自客户端,因此我们只需要改变它。哪一种TrustManager代码行不符合规范? – bnguyen82 2012-03-06 06:25:10

+5

getAcceptedIssuers()指定永不返回null。您发布的代码根本不安全。它不能解决任何问题,它只会产生另一个问题,例如易受中间人攻击。 – EJP 2012-03-06 07:29:38

14

过期的证书是我们的“javax.net.ssl.SSLPeerUnverifiedException:对象未通过身份验证”的原因。

的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 
+0

请原谅“愚蠢”的问题,但已过期的证书位于服务器端或客户端? – isapir 2017-04-14 20:44:37

+0

@Igal如果我准确地记得,服务器端。 – buzz3791 2017-04-26 14:11:56

1

,如果你正试图连接通过HTTPS和服务器没有配置正确处理SSL连接,这也可能发生。

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

+1

什么可配置错误? ssl证书在浏览器中正常工作。为什么它不适用于Java?为什么Java如此特别? – 2013-08-26 21:48:54

-5

如果您处于dev模式并且没有有效的证书,为什么不直接设置weClient.setUseInsecureSSL(true)。适用于我

+0

这不是OP所要求的 – 2016-11-16 06:38:18

6

如果您的服务器基于JDK 7并且您的客户端位于JDK 6并使用SSL证书,则会发生此异常。在JDK 7中,sslv2hello消息握手默认处于禁用状态,而在JDK 6中sslv2hello消息握手处于启用状态。因为这个原因,当你的客户端试图连接服务器时,sslv2hello消息将被发送到服务器,并且由于sslv2hello消息禁用,你将得到这个异常。要解决这个问题,您必须将您的客户端移至JDK 7,否则您必须使用JDK的6u91版本。但要获得此版本的JDK,您必须获得MOS(My Oracle Support)企业支持。这个补丁不公开。

0

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

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

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

2

你可以,如果客户端指定得到这个“https”,但服务器只运行“http”。所以,服务器不希望建立安全的连接。

相关问题