The correct way to install a PEM certificate on Android

I am developing an Android project.

I have a PEM certificate string:

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

(assigned certificate string to a variable named CERT_STR )

I decode the above PEM string into a byte array:

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

I am trying to programmatically install a PEM certificate on my Android phone by running the following code:

 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); 

When I run my code (on an Android 7 device), the Android system certificate installer application pops up a window, when I click the "OK" button of this window, I get the following log:

  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) 

My questions:

  • I used EXTRA_CERTIFICATE and set it to intent , I DO NOT use EXTRA_PKCS12 , but from the log the Android system thinks that I am installing PKCS # 12 key store. Why?

  • What is the correct way to programmatically install a PEM certificate in Android?

+6
source share
1 answer

Your code should work as @Sergey Nikitin said. This tagged example on Github uses similar code.

I reviewed the source code of Android 7.1 CredentialHelper and CertInstaller to track the exception log. A unique way to execute the pkcs12 bootloader when

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

- onScreenlockOk method

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

which is protected by CredentialHelper.hasPkcs12KeyStore()

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

I did not find the default values ​​or alternative paths, so I understand that KeyChain.EXTRA_PKCS12 used in some way. This is weird behavior, maybe you have a problem with a clean reboot?

I suggest debugging code, including the Android CertInstaller class, to provide values ​​for additional functions and ensure that the code that is executed is expected

0
source

Source: https://habr.com/ru/post/1012064/


All Articles