【问题标题】:install X509 certificate programmatically in my case在我的情况下以编程方式安装 X509 证书
【发布时间】:2017-03-20 18:36:04
【问题描述】:

我正在开发一个 Android 项目。我有一个 PEM 证书字符串:

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

(我将上面的证书字符串分配给了一个名为CERT_STR的变量)

我通过以下方式将 PEM 字符串转换为 X509Certificate:

byte[] certBytes = CERT_STR.getBytes();
CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
InputStream certIs = new ByteArrayInputStream(certBytes); 
// now I get the X509 certificate from the PEM string
X509Certificate certificate = (X509Certificate) certificateFactory.generateCertificate(certIs);

然后,我尝试通过以下方式以编程方式安装证书:

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

当我运行我的应用程序时,我看到系统对话框弹出“正在提取...”,我知道系统正在提取我的证书,但该对话框一直显示在那里说“正在提取...”。

为什么?我安装证书的代码哪里错了?

【问题讨论】:

  • 您拥有的代码需要二进制证书,而不是 base64 编码的证书。
  • @Robert,我不太明白你的话,我的代码哪一部分使用了base64编码?
  • BEGIN 和 END CERTIFICATE 之间的部分是 base64 编码的证书。 x.509 CertificateFactory 需要 AFAIR 二进制证书。

标签: android x509certificate keychain pem der


【解决方案1】:

您可能没有使用正确创建的 X509 证书。以下工作对我而言,我没有看到任何“正在提取...”对话框(Nexus 5X,Android 7.0):

String x509cert = "-----BEGIN CERTIFICATE-----\n" +
        "MIICrjCCAhegAwIBAgIJAO9T3E+oW38mMA0GCSqGSIb3DQEBCwUAMHAxCzAJBgNV\n" +
        "BAYTAlVaMREwDwYDVQQHDAhUYXNoa2VudDENMAsGA1UECgwERWZpcjEQMA4GA1UE\n" +
        "CwwHSVQgZGVwdDEQMA4GA1UEAwwHZWZpci51ejEbMBkGCSqGSIb3DQEJARYMaG9z\n" +
        "dEBlZmlyLnV6MB4XDTE2MTExMDA4MjIzMFoXDTE2MTIxMDA4MjIzMFowcDELMAkG\n" +
        "A1UEBhMCVVoxETAPBgNVBAcMCFRhc2hrZW50MQ0wCwYDVQQKDARFZmlyMRAwDgYD\n" +
        "VQQLDAdJVCBkZXB0MRAwDgYDVQQDDAdlZmlyLnV6MRswGQYJKoZIhvcNAQkBFgxo\n" +
        "b3N0QGVmaXIudXowgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAL60mG0Gpl7s\n" +
        "3qMnZcURB1xk5Qen6FN0+AJB5Z/WHA50n1MUkXNY28rkEYupkxpfEqR+/gXgBUAm\n" +
        "FACA3GSdoHMMY1kdeAzxsYbBEbtGKHICF/QFGTqScWmI6uBUwzsLDLv1ELef/zEY\n" +
        "Ru/krXtNh8ZNYyfwVKyZaB9+3M2yOqATAgMBAAGjUDBOMB0GA1UdDgQWBBS1nH3O\n" +
        "ecLDrIZLZ/f1WsNL/xtuEzAfBgNVHSMEGDAWgBS1nH3OecLDrIZLZ/f1WsNL/xtu\n" +
        "EzAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBCwUAA4GBAGzjJnXODvF9UHBKHAUF\n" +
        "kzisr78Og5BrKyAgdnjH196Jg4MO7RNJdQAmuAIk9aBB/jvAiznhhbcD3mYImH+h\n" +
        "F0Scewk5m736ydGhkcUpmxA5ye1hajjs9V7PQD2O4a8rNJSlJjiWRWSqxTfH79Ns\n" +
        "B7x2HND9LU/iz02ugGJ8vwg8\n" +
        "-----END CERTIFICATE-----\n";
Intent intent = KeyChain.createInstallIntent();
intent.putExtra(KeyChain.EXTRA_CERTIFICATE, x509cert.getBytes());
startActivity(intent);

为了生成上述证书,我使用了以下步骤(基于Generating Keys and Certificates for SSO):

$ openssl genrsa -out rsaprivkey.pem 1024

$ openssl req -new -x509 -key rsaprivkey.pem -out rsacert.pem

$ ls
rsacert.pem rsaprivkey.pem

然后我只需将输出从cat rsacert.pem 复制/粘贴到x509cert

希望这会有所帮助。

【讨论】:

  • @ozbek,你在 Android 7 Nougat 设备上测试过吗?我在 Android 7 中遇到了这个问题。
  • @Leem.fin:是的,在装有 Android 7.0 的 Nexus 5X 上测试
  • @ozbek,我刚刚意识到我所拥有的是一个证书也包含私钥。如果你尝试这样做,你会遇到同样的问题。您知道如何在 Android 7 中以编程方式安装包含私钥的证书吗?
  • 我认为你不能在 android 中以编程方式安装任何 CA 证书,这是为了避免中间人攻击。
猜你喜欢
  • 2014-09-01
  • 2023-03-23
  • 2014-12-16
  • 2012-09-29
  • 2012-07-24
  • 2012-09-02
  • 1970-01-01
  • 2010-11-28
相关资源
最近更新 更多