Android Marshmallow查看用户证书并将证书与私钥相关联

时间:2016-08-23 21:03:31

标签: android security certificate android-6.0-marshmallow keystore

  1. 我创建了一个密钥对,将私钥存储在AndroidKeystore中。
  2. 使用密钥对中的公钥
  3. 生成CSR
  4. 将CSR导出到CA,并使其生成证书
  5. 在手机上安装证书
  6. 现在,我正在尝试将#1中的私钥与步骤#4中安装的证书相关联。

    看了一整天,都找不到机制去做。 Android文档建议使用KeyStore.setKeyEntry方法。我打算使用它,但无法读取已安装的证书。

    我可以在AndroidCAStore中显示所有证书,我确实在手机的“用户证书”部分看到了这个新安装的证书,但无法以编程方式阅读。有什么想法吗?

1 个答案:

答案 0 :(得分:0)

尝试做同样的事情。与签名证书的密钥关联也可以使用keystore.setEntry。我无法工作的是这个用户证书然后出现在" IPSec用户证书"尝试添加VPN时的列表框。在Marshmallow 6.0.1上运行

我的逻辑看起来像这样             keyStore = KeyStore.getInstance(" AndroidKeyStore");

        keyGen = KeyPairGenerator.getInstance("EC", "AndroidKeyStore");

        keyGen.initialize(
                new KeyGenParameterSpec.Builder(
                        "myAlias",
                        KeyProperties.PURPOSE_SIGN)
                        .setAlgorithmParameterSpec(new ECGenParameterSpec("secp384r1"))
                        .setDigests(KeyProperties.DIGEST_SHA256,
                                KeyProperties.DIGEST_SHA384,
                                KeyProperties.DIGEST_SHA512)
                        .setBlockModes(KeyProperties.BLOCK_MODE_GCM)
                        .setUserAuthenticationRequired(false)
                        .setKeyValidityStart(now)
                        .setKeyValidityForOriginationEnd(nowPlusThreeYears)
                        .build());

  keyPair = keyGen.generateKeyPair();
  privateKey = (PrivateKey) keyStore.getKey("myAlias", null);
  publicKey = keyStore.getCertificate("myAlias").getPublicKey();

  Certificate[] chain = keyStore.getCertificateChain("myAlias");
  keyStore.setKeyEntry("myAlias", privateKey, null, chain);

  StringBuilder x500PrincipalBuilder = new StringBuilder("CN=");
    x500PrincipalBuilder.append("My Company");
    x500PrincipalBuilder.append(", ");
    x500PrincipalBuilder.append("L=");
    x500PrincipalBuilder.append("My Location");
    x500PrincipalBuilder.append(", ");
    x500PrincipalBuilder.append("ST=");
    x500PrincipalBuilder.append("CA");
    x500PrincipalBuilder.append(", ");
    x500PrincipalBuilder.append("O=");
    x500PrincipalBuilder.append("My Org");
    x500PrincipalBuilder.append(", ");
    x500PrincipalBuilder.append("OU=");
    x500PrincipalBuilder.append("my ou");
    x500PrincipalBuilder.append(", ");
    x500PrincipalBuilder.append("C=");
    x500PrincipalBuilder.append("US");

  Signature ecdsaSignature = Signature.getInstance("SHA384withECDSA");
  ecdsaSignature.initSign(keyPair.getPrivate());

  byte[] strByte = new byte[0];
  strByte = x500PrincipalBuilder.toString().getBytes(UTF8_CHARSET);
  ecdsaSignature.update(strByte);


    X500Principal x500Principal = new X500Principal(x500PrincipalBuilder.toString());
    PKCS10CertificationRequestBuilder p10Builder = new JcaPKCS10CertificationRequestBuilder(
            x500Principal, keyPair.getPublic());

    JcaContentSignerBuilder csBuilder = new JcaContentSignerBuilder(signatureGenerator.getSigningAlgorithm());
    ContentSigner signer = csBuilder.build(keyPair.getPrivate());

    org.bouncycastle.pkcs.PKCS10CertificationRequest csr = p10Builder.build(signer);

    PemObject pemObject = new PemObject("CERTIFICATE REQUEST", csr.getEncoded());
    StringWriter str = new StringWriter();
    PEMWriter pemWriter = new PEMWriter(str);
    pemWriter.writeObject(pemObject);
    pemWriter.close();
    str.close();


// write the csr to a file
// get it signed by the CA (Microsoft CA)
// Push the cert to the phone
// Install the cert

Certificate clientCertSignedByCA = CertificateFactory.getInstance("X.509").generateCertificate(new FileInputStream("/path/to/cert.cer));
    KeyStore.Entry entry = keyStore.getEntry("myAlias", null);
PrivateKey privateKey = (PrivateKey) keyStore.getKey("myAlias", null);
Certificate[] chain = new Certificate[1];
chain[0] = clientCertSignedByCA;
keyStore.setKeyEntry("myAlias", privateKey, null, chain);