2013-03-01 32 views
1

我試圖使用clientAuth = true &配置Tomcat6自簽名證書,然後調用客戶端上的Tomcat服務器使用HttpClient 4.1.x.自簽名證書的HttpClient 4.1.x錯誤(javax.net.ssl.SSLPeerUnverifiedException:未通過身份驗證的對象)

我跟着http://virgo47.wordpress.com/2010/08/23/tomcat-web-application-with-ssl-client-certificates/ &當我從瀏覽器或從OpenSSL的客戶端測試,預計這是工作的罰款規定(我跑命令「指令的OpenSSL的s_client.First -cert client.crt - 鍵client.key - CAfile ca.crt -connect localhost:8443「)。

我面臨的問題是與HttpClient。我寫了下面的代碼來創建HttpClient的

private DefaultHttpClient creatHttpClient(KeyStore keyStore, 
     char[] keyStorePassword, KeyStore trustStore, char[] trustStorePassword) { 
    try { 

     TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(
       TrustManagerFactory.getDefaultAlgorithm()); 
     trustManagerFactory.init(trustStore); // This contains CA certs 
     TrustManager[] tm = trustManagerFactory.getTrustManagers(); 

     KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(
       KeyManagerFactory.getDefaultAlgorithm()); 
     keyManagerFactory.init(keyStore, keyStorePassword); // This contain client private key 
     KeyManager[] km = keyManagerFactory.getKeyManagers(); 

     SSLContext sslContext = SSLContext.getInstance("TLS"); 
     sslContext.init(km, tm, new SecureRandom()); 

     SSLSocketFactory sslSocketFactory = new SSLSocketFactory(sslContext, 
       SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER); 

     HttpParams params = new BasicHttpParams(); 
     HttpConnectionParams.setConnectionTimeout(params, 10000); 
     HttpConnectionParams.setSoTimeout(params, 30000); 

     SchemeRegistry schemeRegistry = new SchemeRegistry(); 
     schemeRegistry.register(new Scheme("https", 
       443, sslSocketFactory)); 

     ClientConnectionManager clientConnectionManager = 
       new ThreadSafeClientConnManager(schemeRegistry); 

     final DefaultHttpClient httpClient = new DefaultHttpClient(
       clientConnectionManager, params); 
     return httpClient; 
    } catch(Exception e) { 
     throw e; 
    } 
} 

對於這一點,我收到

javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated 

我啓用

static 
    { System.setProperty("javax.net.debug", "ssl,handshake,trustmanager"); } 

我收到了調試以下調試日誌

main, handling exception: java.lang.RuntimeException: Unexpected error:      java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty 
    main, SEND TLSv1 ALERT: fatal, description = internal_error 
    main, WRITE: TLSv1 Alert, length = 2 
    main, called closeSocket() 
    main, IOException in getSession(): javax.net.ssl.SSLException: java.lang.RuntimeException: Unexpected error: java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty 
    main, called close() 
    main, called closeInternal(true) 
    main, called close() 
    main, called closeInternal(true) 

什麼可以b在這種情況下可能會出錯?我不想忽略ssl證書錯誤,而是想正確地進行身份驗證。

回答

0

我解決了我自己的問題。問題是,我用

InputStream ksin = this.getClass().getResourceAsStream("client.jks"); 
InputStream tsin = this.getClass().getResourceAsStream("cacerts.jks"); 

&加載密鑰庫&信任存儲使用的是JUnit這些線路測試&它無法找到.jks文件。

我通過將以下

if(0 == keyStore.size()) { throw new RuntimeException("Keystore is empty"); } 
if(0 == trustStore.size()) { throw new RuntimeException("Truststore is empty"); } 

密鑰庫&信任初始化後想通了這一點。

於是,我改變了線路

InputStream ksin = Thread.currentThread().getContextClassLoader().getResourceAsStream("client.jks"); 
InputStream tsin = Thread.currentThread().getContextClassLoader().getResourceAsStream("cacerts.jks"); 

&一切正常。

相關問題