2012-03-04 57 views
3

A server和各自的client支持客戶端身份驗證,但如此處所述:SSLHandshakeException: no cipher suites in common,沒有trustStore引用,即它們使用默認的trustStore。如何指定trustStore?爲客戶端身份驗證添加trustStore

ClassFileServer:

private static ServerSocketFactory getServerSocketFactory(String type) { 
    if (type.equals("TLS")) { 
     SSLServerSocketFactory ssf = null; 

     Properties systemProps = System.getProperties(); 
     systemProps.put("javax.net.ssl.trustStore", "cacerts.jks"); 
     systemProps.put("javax.net.ssl.trustStorePassword", "[email protected]"); 
     System.setProperties(systemProps); 

     try { 
      // set up key manager to do server authentication 
      SSLContext ctx; 
      KeyManagerFactory kmf; 
      KeyStore ks; 
      char[] passphrase = "[email protected]".toCharArray(); 

      ctx = SSLContext.getInstance("TLS"); 
      kmf = KeyManagerFactory.getInstance("SunX509"); 
      ks = KeyStore.getInstance("JKS"); 
      ks.load(new FileInputStream("keystore.jks"), passphrase); 
      kmf.init(ks, passphrase); 
      ctx.init(kmf.getKeyManagers(), null, null); 

      ssf = ctx.getServerSocketFactory(); 
      return ssf; 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
    } 

SSLSocketClientWithClientAuth:

try { 

     /* 
     * Set up a key manager for client authentication 
     * if asked by the server. Use the implementation's 
     * default TrustStore and secureRandom routines. 
     */ 
     Properties systemProps = System.getProperties(); 
     systemProps.put("javax.net.ssl.trustStore", "cacerts.jks"); 
     systemProps.put("javax.net.ssl.trustStorePassword", "changeit"); 
     System.setProperties(systemProps); 

     SSLSocketFactory factory = null; 
     try { 
      SSLContext ctx; 
      KeyManagerFactory kmf; 
      KeyStore ks; 
      char[] passphrase = "changeit".toCharArray(); 

      ctx = SSLContext.getInstance("TLS"); 
      kmf = KeyManagerFactory.getInstance("SunX509"); 
      ks = KeyStore.getInstance("JKS"); 

      ks.load(new FileInputStream("keystore.jks"), passphrase); 

      kmf.init(ks, passphrase); 
      ctx.init(kmf.getKeyManagers(), null, null); 

      factory = ctx.getSocketFactory(); 
     } catch (Exception e) { 
      throw new IOException(e.getMessage()); 
     } 

     SSLSocket socket = (SSLSocket)factory.createSocket(host, port); 
+0

定義 '更好'。 – EJP 2015-03-22 16:47:45

回答

2

通過設置系統屬性指定trustStore

System.setProperty("javax.net.ssl.trustStore", "cacerts.jks");

或經由命令行調用:

-Djavax.net.ssl.keyStore=path/to/keystore.jks

+2

如果你指出瞭如何做到這一點我會+1這個答案... – rexford 2014-09-10 07:12:36

+2

什麼是/是'systemProps'? – EJP 2015-03-22 16:48:28

+0

systemProps是系統屬性,已經明確答案。 – Astron 2017-10-17 00:16:43

1

'沒有共同的密碼套件' 不使用默認的信任造成的。這是由於沒有密鑰庫,或者沒有私鑰和證書,或者通過在一個對等或另一個對等處過度指定密碼套件而導致沒有協議。

如果服務器沒有私有密鑰,它不能使用任何密碼套件,除了不安全匿名的,這是默認禁用,並應保持這種方式。因此警報。

使用默認的信任將導致不同問題當且僅當您正在使用自簽名的證書。簡單的解決方案:不要。更復雜的解決方案:從各自的密鑰存儲導出相應的證書,並將它們導入到對方信任。

JSSE Reference Guide

+0

新增systemProps其作品,但似乎並不優美,我記得讀某處* *是不理想(雖然我無法找到參考)? – Astron 2012-03-04 15:44:22

+0

@Astron看起來比較難,關於使用自定義TrustManagerz的部分。 – EJP 2012-03-05 00:17:29

+0

我看到使用自定義TrustManger [這裏](http://docs.oracle.com/javase/6/docs/technotes/guides/security/jsse/JSSERefGuide.html#CustomizingStores)引用,但不知道在哪裏讀一個'trustStore'詩''keyStore',幾乎似乎是一個相同的。 – Astron 2012-03-05 12:13:59