2012-03-06 39 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」。所以,服務器不希望建立安全的連接。

相關問題