2016-11-05 108 views
6

我正在開發一個Android項目。在Android中安裝PEM證書的正確方法

我有一個PEM證書字符串:

-----BEGIN CERTIFICATE----- 
MIIEczCCA1ugAwIBAgIBADANBgkqhkiG9w0BAQQFAD..AkGA1UEBhMCR0Ix 
EzARBgNVBAgTClNvbWUtU3RhdGUxFDASBgNVBAoTC0..0EgTHRkMTcwNQYD 
VQQLEy5DbGFzcyAxIFB1YmxpYyBQcmltYXJ5IENlcn..XRpb24gQXV0aG9y 
...MANY LINES... 
It8una2gY4l2O//on88r5IWJlm1L0oA8e4fR2yrBHX..adsGeFKkyNrwGi/ 
7vQMfXdGsRrXNGRGnX+vWDZ3/zWI0joDtCkNnqEpVn..HoX 
-----END CERTIFICATE----- 

(以上證書字符串指定給名爲CERT_STR一個變量)

我解碼上述PEM字符串字節數組:

byte[] pemBytes = Base64.decode(
       CERT_STR.replaceAll("-----(BEGIN|END) CERTIFICATE-----", "") 
         .replaceAll("\n", "") 
         .getBytes("UTF-8"), 
       Base64.DEFAULT 
     ); 

我嘗試通過以下代碼以編程方式將PEM證書安裝到我的Android手機:

Intent intent = KeyChain.createInstallIntent(); 
// because my PEM only contains a certificate, no private key, so I use EXTRA_CERTIFICATE 
intent.putExtra(KeyChain.EXTRA_CERTIFICATE, pemBytes);// above PEM bytes 
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 
context.startActivity(intent); 

當我的代碼運行(在Android的7設備),Android系統的證書安裝程序彈出的窗口,當我按下「OK」該窗口的按鈕,我得到了以下日誌:

java.io.IOException: stream does not represent a PKCS12 key store 
    at com.android.org.bouncycastle.jcajce.provider.keystore.pkcs12.PKCS12KeyStoreSpi.engineLoad(PKCS12KeyStoreSpi.java:793) 
    at java.security.KeyStore.load(KeyStore.java:1247) 
    at com.android.certinstaller.CredentialHelper.loadPkcs12Internal(CredentialHelper.java:396) 
    at com.android.certinstaller.CredentialHelper.extractPkcs12Internal(CredentialHelper.java:364) 
    at com.android.certinstaller.CredentialHelper.extractPkcs12(CredentialHelper.java:354) 
    at com.android.certinstaller.CertInstaller$1.doInBackground(CertInstaller.java:328) 
    at com.android.certinstaller.CertInstaller$1.doInBackground(CertInstaller.java:327) 

我的問題:

  1. 我用EXTRA_CERTIFICATE &將其設置爲intent,我沒有使用EXTRA_PKCS12,但是從日誌中,Android的SY stem認爲我正在安裝PKCS#12密鑰存儲庫。爲什麼?

  2. 在Android中以編程方式安裝PEM證書的正確方法是什麼?

+0

'流不代表PKCS12關鍵store'任何理由不嘗試將其轉換到PKCS12呢? –

+0

但我仍然想知道在Android中安裝PEM的正確方法是什麼,這是我的問題。 –

+0

這似乎是完全重複的https://stackoverflow.com/questions/40464815/install-x509-certificate-programmatically-in-my-case – ozbek

回答

0

您的代碼應該如@Sergey Nikitin所說的那樣工作。焦點複製example Github使用類似的代碼

我已閱讀並通過CredentialHelperCertInstaller的Android 7.1源代碼來跟蹤您的異常日誌。獨特的可到達路徑在

com.android.certinstaller.CredentialHelper.extractPkcs12(CredentialHelper.java:354) 

執行pkcs12裝載機是由CredentialHelper.hasPkcs12KeyStore()

boolean hasPkcs12KeyStore() { 
    return mBundle.containsKey(KeyChain.EXTRA_PKCS12); 
} 

我還沒有發現默認分配的值或可替代的路徑保護的方法onScreenlockOk

private void onScreenlockOk() { 
    if (mCredentials.hasPkcs12KeyStore()) { 
     if (mCredentials.hasPassword()) { 
      showDialog(PKCS12_PASSWORD_DIALOG); 
     } else { 
      new Pkcs12ExtractAction("").run(this); 
     } 

,所以我推斷KeyChain.EXTRA_PKCS12正在以某種方式使用。這是一個奇怪的行爲,可能是你有一個乾淨的&重建問題?

我建議調試包括Android CertInstaller類的代碼,以確保額外的價值,並確保執行的代碼是預期