2017-02-24 62 views
0

我有一個包含多個客戶端證書的java密鑰庫文件。我希望在我的Java應用程序中僅選擇其中一個證書來連接到服務。有沒有簡單的方法來做到這一點?到目前爲止,我找到解決方案的唯一方法是使用原始密鑰庫文件中的客戶端證書詳細信息(通過其別名找到)在程序中創建一個新的KeyStore。我雖然可能只是簡單地說「使用帶有這個別名的keystore.jks文件中的證書」,而不是僅僅爲你想使用的證書創建一個新的密鑰庫。代碼如下:Java密鑰庫 - 以編程方式從密鑰庫文件中選擇要使用的證書

 // Set up Client Cert settings 
     KeyStore clientCertStore = KeyStore.getInstance("JKS"); 
     clientCertStore.load(new FileInputStream(clientKeystoreLocation), clientKeystorePassword);    

     // Create temporary one keystore, then extract the client cert using it's alias from keystore.jks, then create 
     // a new keystore with this cert, that the process will use to connect with. 
     KeyStore tempKstore = KeyStore.getInstance("JKS"); 
     tempKstore.load(null); 
     tempKstore.setKeyEntry(certificateAlias, clientCertStore.getKey(certificateAlias, bwConfig.clientKeystorePassword), 
       clientKeystorePassword, clientCertStore.getCertificateChain(certificateAlias)); 
     clientCertStore = tempKstore; 

     KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); 
     keyManagerFactory.init(clientCertStore, clientKeystorePassword);    

     // Set up Truststore settings 
     File truststoreFile = new File(TrustStoreLocation); 
     KeyStore trustStore = KeyStore.getInstance("JKS"); 
     trustStore.load(new FileInputStream(truststoreFile), TrustStorePassword); 
     TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); 
     trustManagerFactory.init(trustStore); 

     // Set to TLS 1.2 encryption 
     SSLContext sslContext = SSLContext.getInstance("TLSv1.2"); 
     sslContext.init(keyManagerFactory.getKeyManagers(), trustManagerFactory.getTrustManagers(), null); 

     SSLSocketFactory ssf = sslContext.getSocketFactory(); 
     ssf.createSocket(serviceURL.getHost(), servicePort); 

     bp.getRequestContext().put("com.sun.xml.internal.ws.transport.https.client.SSLSocketFactory", ssf); 

回答

0

你的問題是類似How I can tell alias of the wanted key-entry to SSLSocket before connecting?

默認KeyManager將選擇在握手的第一個證書(根據服務器發送的CA列表中),你可以建立自己的X509KeyManager指定要使用的別名包裝默認值。

final X509KeyManager origKm = (X509KeyManager)keyManagerFactory.getKeyManagers()[0]; 
X509KeyManager km = new X509KeyManager() { 
    public String chooseClientAlias(String[] keyType, Principal[] issuers, Socket socket) { 
     return "alias"; 
    } 

    public X509Certificate[] getCertificateChain(String alias) { 
     return origKm.getCertificateChain(alias); 
    } 

// override the rest of the methods delegating to origKm ... 
} 

坐落在SSLContext

sslContext.init(new KeyManager[] { km }, trustManagerFactory.getTrustManagers(), null); 
keyManager
相關問題