使用AndroidKeyStoreProvider生成证书签名请求的最佳方法是什么?

时间:2014-09-18 08:04:08

标签: java android certificate keystore csr

我已阅读这篇文章https://developer.android.com/training/articles/keystore.html

生成密钥对有好处。 但是,它并没有告诉如何根据生成密钥生成证书签名请求。

从我的研究来看,要在java中生成CSR,来自Web的样本通常使用包sun.*或BouncyCastle库。似乎无法使用标准java.sercurity API生成CSR。我读了这个Possible to generate CSR using java.security without sun packages or external library?。似乎是真的。

除了使用BouncyCastle之外别无选择吗?很难想象Android开发者不会考虑这种用法。

顺便说一下,文章还提到:

Generating a new PrivateKey requires that you also 
specify the initial X.509 attributes that the self-signed certificate 
will have. You can replace the certificate at a later time with a certificate 
signed by a Certificate Authority

假设我最终获得证书颁发机构签署的证书。我该怎么做才能在以后更换证书"?

2 个答案:

答案 0 :(得分:2)

关于在Android手机上生成CSR(证书签名请求),我认为使用Spongycastle相当简单。它是Bouncycastle的Android端口。

  

假设我最终获得证书颁发机构签署的证书。   我该怎么办?"稍后更换证书"?

如果您拥有应从CA(证书颁发机构)获得的实际签名证书,则不再需要您的CSR;您应该只将已签名的证书存储在手机上。在哪里保存它们 - 我想你可以得到帮助here

答案 1 :(得分:1)

在Android上创建CSR的最佳方法是使用SpongyCastle,它是BouncyCastle在Android上的实现。 SpongyCastle已经为您完成了许多繁重的工作,因此它将使您的生活更加轻松。


我的实现很大程度上基于找到的答案here,但是为了安全起见,使用Android KeyStore和SpongyCastle的JcaContentSignerBuilder()而非自定义ContentSigner

将SpongyCastle添加到您的build.gradle文件中:

compile 'com.madgag.spongycastle:core:1.51.0.0'
compile 'com.madgag.spongycastle:pkix:1.51.0.0'

Android KeyStore中创建密钥对:

KeyPairGenerator keyGen = KeyPairGenerator.getInstance(KeyProperties.KEY_ALGORITHM_RSA, "AndroidKeyStore"); // store the key in the Android KeyStore for security purposes
keyGen.initialize(new KeyGenParameterSpec.Builder(
                  "key1",
                  KeyProperties.PURPOSE_SIGN)
                  .setSignaturePaddings(KeyProperties.SIGNATURE_PADDING_RSA_PKCS1)
                  .setDigests(KeyProperties.DIGEST_SHA256,
                                KeyProperties.DIGEST_SHA384,
                                KeyProperties.DIGEST_SHA512)
                  .build()); // defaults to RSA 2048
KeyPair keyPair = keyGen.generateKeyPair();

使用所述密钥对创建CSR:

private final static String CN_PATTERN = "CN=%s, O=Aralink, OU=OrgUnit";

//Create the certificate signing request (CSR) from private and public keys
public static PKCS10CertificationRequest generateCSR(KeyPair keyPair, String cn) throws IOException, OperatorCreationException {
        String principal = String.format(CN_PATTERN, cn);

        ContentSigner signer = new JcaContentSignerBuilder(DEFAULT_RSA_SIGNATURE_ALGORITHM).build(keyPair.getPrivate());

        PKCS10CertificationRequestBuilder csrBuilder = new JcaPKCS10CertificationRequestBuilder(
                new X500Name(principal), keyPair.getPublic());
        ExtensionsGenerator extensionsGenerator = new ExtensionsGenerator();
        extensionsGenerator.addExtension(Extension.basicConstraints, true, new BasicConstraints(
                true));
        csrBuilder.addAttribute(PKCSObjectIdentifiers.pkcs_9_at_extensionRequest,
                extensionsGenerator.generate());
        PKCS10CertificationRequest csr = csrBuilder.build(signer);

        return csr;
    }
}

就这样,现在您可以将PKCS10CertificationRequest发送到服务器了。