2011-11-29 212 views
1

我試圖在android中使用客戶端證書。 我得到了一個.p12文件,我想用它來對服務器進行身份驗證。如何在Android中使用p12證書(客戶端證書)

我正在使用portecle將.p12文件轉換爲.bks文件,但我似乎沒有得到它的工作。

下面的代碼:

package com.pa1406.SECURE; 

import java.io.InputStream; 
import java.security.KeyStore; 

import javax.net.ssl.KeyManagerFactory; 
import javax.net.ssl.TrustManagerFactory; 

import org.apache.http.conn.ClientConnectionManager; 
import org.apache.http.conn.scheme.PlainSocketFactory; 
import org.apache.http.conn.scheme.Scheme; 
import org.apache.http.conn.scheme.SchemeRegistry; 
import org.apache.http.conn.ssl.SSLSocketFactory; 
import org.apache.http.impl.client.DefaultHttpClient; 
import org.apache.http.impl.conn.SingleClientConnManager; 

import android.content.Context; 

public class HttpsClient extends DefaultHttpClient { 

    final Context context; 

    public HttpsClient(Context context) { 
    this.context = context; 
    } 

    @Override protected ClientConnectionManager createClientConnectionManager() { 
    SchemeRegistry registry = new SchemeRegistry(); 
    registry.register(
     new Scheme("http", PlainSocketFactory.getSocketFactory(), 80)); 
    registry.register(
     new Scheme("https",newSslSocketFactory(), 443)); 
    return new SingleClientConnManager(getParams(), registry); 
    } 

    private SSLSocketFactory newSslSocketFactory() { 
    try { 
     KeyStore truststore = KeyStore.getInstance("BKS"); 

     InputStream in = context.getResources().openRawResource(R.raw.keystore); 

     try { 
      truststore.load(in, "qwerty1234".toCharArray()); 
     } finally { 
     in.close(); 
     } 
     return new SSLSocketFactory(truststore); 
    } catch (Exception e) { 
     throw new AssertionError(e); 
    } 

    } 
} 

我能做些什麼來實現這一目標?

UPDATE:

package com.pa1406.SECURE; 


import java.io.InputStream; 
import java.security.KeyStore; 

import javax.net.ssl.KeyManagerFactory; 
import javax.net.ssl.SSLContext; 
import javax.net.ssl.TrustManagerFactory; 

import org.apache.http.conn.ClientConnectionManager; 
import org.apache.http.conn.scheme.PlainSocketFactory; 
import org.apache.http.conn.scheme.Scheme; 
import org.apache.http.conn.scheme.SchemeRegistry; 
import org.apache.http.conn.ssl.SSLSocketFactory; 
import org.apache.http.impl.client.DefaultHttpClient; 
import org.apache.http.impl.conn.SingleClientConnManager; 

import android.content.Context; 

public class HttpsClient extends DefaultHttpClient { 

    final Context context; 

    public HttpsClient(Context context) { 
    this.context = context; 
    } 

    @Override protected ClientConnectionManager createClientConnectionManager() { 
    SchemeRegistry registry = new SchemeRegistry(); 
    registry.register(
     new Scheme("http", PlainSocketFactory.getSocketFactory(), 80)); 
    registry.register(
     new Scheme("https",newSslSocketFactory(), 443)); 
    return new SingleClientConnManager(getParams(), registry); 
    } 

    private SSLSocketFactory newSslSocketFactory() { 
    try { 
     // setup truststore to provide trust for the server certificate 

     // load truststore certificate 
     InputStream clientTruststoreIs = context.getResources().openRawResource(R.raw.truststore); 
     KeyStore trustStore = null; 
     trustStore = KeyStore.getInstance("BKS"); 
     trustStore.load(clientTruststoreIs, "qwerty1234".toCharArray()); 

     System.out.println("Loaded server certificates: " + trustStore.size()); 

     // initialize trust manager factory with the read truststore 
     TrustManagerFactory trustManagerFactory = null; 
     trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); 
     trustManagerFactory.init(trustStore); 

     // setup client certificate 

     // load client certificate 
     InputStream keyStoreStream = context.getResources().openRawResource(R.raw.torbix); 
     KeyStore keyStore = null; 
     keyStore = KeyStore.getInstance("BKS"); 
     keyStore.load(keyStoreStream, "qwerty1234".toCharArray()); 

     System.out.println("Loaded client certificates: " + keyStore.size()); 

     // initialize key manager factory with the read client certificate 
     KeyManagerFactory keyManagerFactory = null; 
     keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); 
     keyManagerFactory.init(keyStore, "qwerty1234".toCharArray()); 

    // initialize SSLSocketFactory to use the certificates 
     SSLSocketFactory socketFactory = null; 
     socketFactory = new SSLSocketFactory(SSLSocketFactory.TLS, keyStore, "qwerty1234", 
      trustStore, null, null); 

     return socketFactory; 
    } catch (Exception e) { 
     throw new AssertionError(e); 
    } 

    } 

} 

回答

3

,你必須改變你的代碼是當你的新的SSLSocketFactory實例的點:

return new SSLSocketFactory(truststore); 

的類SSLSocketFactory具有其他構造,其中一個允許指定密鑰庫,密鑰庫密碼和可信度:

public SSLSocketFactory (KeyStore keystore, String keystorePassword, KeyStore truststore)JavaDoc

我不確定您是否可以在Android下將您的.P12文件加載爲KeyStore(在J2SE上可以)。如果您不能將.P12文件轉換爲與您已使用的信任庫類似的Bouncy城​​堡密鑰庫。使用該密鑰存儲來創建您的SSLSocketFactory實例,並且您應該能夠使用客戶端證書。

通過Portecle

導入P12文件到BKS創建BKS文件,並導入現有.key + .pem文件使用Portecle GUI(Java程序)是非常簡單的。啓動Portecle後,請選擇文件 - >新密鑰庫 - > BKS。之後,您可以執行工具 - >導入密鑰對並選擇.P12文件。 最後保存用您選擇的密碼保護的密鑰存儲區。

+0

我試圖使用.p12文件,但它沒有工作,需要將其轉換。我不確定我是否正確。我會更新這個問題,所以你可以現在就是我。 – Bewn

+0

對於轉換P12-> BKS我會使用工具[Portecle](http://portecle.sourceforge.net) - 如果你更喜歡GUI而不是命令行。 – Robert

+0

這就是我正在使用的,我該如何轉換它?我是否打開帶有portecle的.p12並導出密鑰和證書,然後將它們添加到我的新密鑰庫中,還是應該執行其他操作? :) – Bewn