2014-01-28 41 views
0

我試圖安裝服務器端客戶端aith在我的Java應用程序如下:無法設置客戶端X509身份驗證在Java中

SslContextFactory sslContextFactory = new SslContextFactory(); 
sslContextFactory.setNeedClientAuth(true); 

TrustManager[] trustManagers = new TrustManager[ 
     ]{new X509TrustManager() { 
    @Override 
    public void checkClientTrusted(X509Certificate[] arg0, String arg1) 
      throws CertificateException { 
     LoggerFactory.getLogger().fatal("Check client trusted"); 
    } 

    @Override 
    public void checkServerTrusted(X509Certificate[] arg0, String arg1) 
      throws CertificateException { 
     LoggerFactory.getLogger().fatal("Check server trusted"); 
    } 

    @Override 
    public X509Certificate[] getAcceptedIssuers() { 
     LoggerFactory.getLogger().fatal("Returning accepted issuers"); 

     try { 
      InputStream inStream = new FileInputStream("/home/sk_/client.cer"); 
      CertificateFactory cf = CertificateFactory.getInstance("X.509"); 
      X509Certificate cert = (X509Certificate) cf.generateCertificate(inStream); 
      inStream.close(); 

      return new X509Certificate[]{cert}; 
     } catch (Exception e) { 
      e.printStackTrace(); 
      LoggerFactory.getLogger().fatal("AFDASDFSAASD", e); 

      return null; 
     } 
    } 
}}; 

SSLContext context = SSLContext.getInstance("TLSv1.1"); 
KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509"); 
FileInputStream fin = new FileInputStream(".hive/certs/mjolnirr.jks"); 
KeyStore ks = KeyStore.getInstance("JKS"); 
ks.load(fin, "passwd".toCharArray()); 

kmf.init(ks, "passwd".toCharArray()); 
context.init(kmf.getKeyManagers(), trustManagers, null); 

SSLEngine engine = context.createSSLEngine(); 
engine.setNeedClientAuth(true); 
engine.setEnabledCipherSuites(engine.getSupportedCipherSuites()); 
engine.setEnabledProtocols(engine.getSupportedProtocols()); 

sslContextFactory.setSslContext(context); 

而且我已經添加SSL設置客戶端:

-Djavax.net.debug=ssl 
-Djavax.net.ssl.keyStoreType=jks 
-Djavax.net.ssl.keyStore=/home/sk_/client-truststore.jks 
-Djavax.net.ssl.keyStorePassword=passwd 
-Djavax.net.ssl.trustStoreType=jks 
-Djavax.net.ssl.trustStore=/home/sk_/client-truststore.jks 
-Djavax.net.ssl.trustStorePassword=passwd 

client.cer從客戶端信任庫(client-trustore.jks)中導出。客戶失敗,出現以下錯誤:

javax.net.ssl.SSLHandshakeException: Remote host closed connection during handshake 
at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:946) 
at sun.security.ssl.SSLSocketImpl.waitForClose(SSLSocketImpl.java:1705) 
at sun.security.ssl.HandshakeOutStream.flush(HandshakeOutStream.java:122) 
at sun.security.ssl.Handshaker.sendChangeCipherSpec(Handshaker.java:972) 
at sun.security.ssl.ClientHandshaker.sendChangeCipherAndFinish(ClientHandshaker.java:1087) 
... 

我的應用程序有什麼問題?

編輯我添加調試的sslhandshake到服務器,這裏是輸出:

*** ServerHelloDone 
qtp935608254-28, WRITE: TLSv1 Handshake, length = 1442 
qtp935608254-29, READ: TLSv1 Handshake, length = 77 
*** Certificate chain 
*** 
qtp935608254-29, fatal error: 42: null cert chain 
javax.net.ssl.SSLHandshakeException: null cert chain 
%% Invalidated: [Session-1, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA] 
qtp935608254-29, SEND TLSv1 ALERT: fatal, description = bad_certificate 
qtp935608254-29, WRITE: TLSv1 Alert, length = 2 
qtp935608254-29, fatal: engine already closed. Rethrowing javax.net.ssl.SSLHandshakeException: null cert chain 
+0

請使用-Djavax.net.debug = ssl運行服務器,握手並在此處發佈相關輸出。 – EJP

+0

@EJP請參閱編輯 – skayred

回答

1

您的客戶端證書不是由服務器的信任的信任。服務器發送一個受信任CA的列表,客戶端必須發送其中一個受信任的證書。它不能,所以它發送一個空證書鏈。如果您的客戶端證書是自簽名的或由不受信任的CA簽名的,則需要將其從您的客戶端密鑰庫導出並作爲可信證書導入到服務器的信任庫中。