【问题标题】:A proper way to install PEM certifiate in Android在 Android 中安装 PEM 证书的正确方法
【发布时间】:2016-11-05 19:44:27
【问题描述】:

我正在开发一个 Android 项目。

我有一个 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 系统证书安装程序会弹出窗口,当我按下该窗口的“确定”按钮时,我得到以下日志:

 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 系统认为我正在安装 PKCS#12 密钥库。为什么?

  2. 在 Android 中以编程方式安装 PEM 证书的正确方法是什么?

【问题讨论】:

  • stream does not represent a PKCS12 key store 有什么理由不尝试将其转换为 PKCS12 吗?
  • 但我仍然想知道在 Android 中安装 PEM 的正确方法是什么,这就是我的问题所在。
  • 这似乎与 stackoverflow.com/questions/40464815/… 完全相同
  • 你用的是什么版本的安卓平台?我试图运行你的代码并且运行良好。我看到 Toast “已安装 ”。安卓5.1.0
  • 我在 Android 7 中运行它

标签: android keychain pem pkcs#12


【解决方案1】:

正如@Sergey Nikitin 所说,您的代码应该可以工作。这个在 Github 上星标的 example 正在使用类似的代码

我已经查看了CredentialHelperCertInstaller 的Android 7.1 源代码来跟踪您的异常日志。执行pkcs12 加载程序的唯一可达路径

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

是方法onScreenlockOk

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

CredentialHelper.hasPkcs12KeyStore()保护

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

我没有找到默认分配值或替代路径,所以我推断KeyChain.EXTRA_PKCS12 正在以某种方式使用。这是一种奇怪的行为,可能是您有清理和重建问题吗?

我建议调试包含Android CertInstaller类的代码,以确保Extras的值,并确保执行的代码是预期的

【讨论】:

    猜你喜欢
    • 2020-08-01
    • 2015-11-15
    • 2018-10-21
    • 2020-08-06
    • 2019-03-19
    • 1970-01-01
    • 2019-02-08
    • 2016-05-05
    相关资源
    最近更新 更多