2014-09-23 75 views
1

在我的應用程序中,我需要實現2way握手。 這裏是下面的代碼我使用這個:無法在android握手過程中附加客戶端證書

public static SSLContext getSSLContext() throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, CertificateException, NotFoundException, IOException, UnrecoverableKeyException{ 
    KeyStore clientCertificateKeysKeyStore = getClientCertificateKeystore();  
    KeyStore trustStore = getServerCertificateKeystore(); 
    KeyManagerFactory kmf = KeyManagerFactory.getInstance(X509);  

    if(clientCertificateKeysKeyStore != null) 
     kmf.init(clientCertificateKeysKeyStore, "cleint".toCharArray()); 
    KeyManager[] keyManagers = kmf.getKeyManagers(); 


// TrustManager[] trustManagers = {new CustomTrustManager(trustStore)}; 
    TrustManagerFactory tmf = TrustManagerFactory.getInstance(X509); 
    tmf.init(trustStore); 

    TrustManager[] trustManagers = tmf.getTrustManagers(); 

    SSLContext sslContext = SSLContext.getInstance("TLS"); 
    sslContext.init(keyManagers, trustManagers, null); 
    return sslContext; 

} 

我有我不得不生成密鑰庫PEM文件。

private KeyStore loadPEMKeystoreStore(File certificateFile) throws Exception { 
     InputStream caInput = new BufferedInputStream(new FileInputStream(certificateFile)); 
     byte[] der = loadPemCertificate(caInput); 
     ByteArrayInputStream derInputStream = new ByteArrayInputStream(der); 
     CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509"); 
     X509Certificate cert = (X509Certificate) certificateFactory.generateCertificate(derInputStream); 
     String alias = cert.getSubjectX500Principal().getName(); 

     KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType()); 
     keyStore .load(null); 
     keyStore .setCertificateEntry(alias, cert); 

     return keyStore ; 
    } 

服務器證書是本地存儲的.pk12證書。

問題是客戶端證書在握手過程中未附加。 我用wireshark來分析數據包,它顯示客戶端證書長度爲0.

如果我使用.pk12文件作爲客戶端證書,它會正確連接。 但我必須使用PEM文件。 任何解決方案!

+1

如果「2路」握手你的意思是SSL客戶端身份驗證,則需要客戶端的私有密鑰,而不僅僅是一個證書。目前還不清楚PEM文件包含什麼,但它看起來只包含證書。您需要獲取相應的私鑰並將密鑰+證書轉換爲PKCS#12文件或密鑰存儲文件(Bouncy Castle的BKS)才能使其運行。 – 2014-09-30 08:22:59

+1

非常感謝您的回覆。其實我已經解決了這個問題。你的假設是正確的,PEM文件只包含一個證書。 – 2014-09-30 11:00:40

回答

0

PEM文件只包含證書而非私鑰。這是更新的代碼,它工作正常。

private KeyStore loadPEMKeystoreStore(File certificateFile, String password) throws Exception { 
     InputStream caInput = new BufferedInputStream(new FileInputStream(certificateFile)); 


     KeyStore keystore = KeyStore.getInstance(CLIENT_CERTIFICATE_KEYSTORE_TYPE); 


     CertificateFactory certificateFactory = CertificateFactory 
       .getInstance(X509); 
     X509Certificate cert = (X509Certificate) certificateFactory 
       .generateCertificate(caInput); 


     keystore.load(null); 
     keystore.setCertificateEntry("cert-alias", cert); 
     keystore.setKeyEntry("key-alias", privateKey, password.toCharArray(), 
       new Certificate[]{cert}); 
     FileOutputStream out = new FileOutputStream(file); 
     keystore.store(out, password.toCharArray()); 

     return keyStore ; 
    }