[英]What is the best way to generate Certificate Signing Request using AndroidKeyStoreProvider?
I read this article .我读 了这篇文章。
It says how to generate a KeyPair
, however it doesn't specify how to generate a Certificate Signing Request based on the generated keys.它说明了如何生成
KeyPair
,但是它没有指定如何根据生成的密钥生成证书签名请求。
From my research, to generate a CSR in Java, the samples from the web usually use the package sun.*
or the BouncyCastle library.根据我的研究,要在 Java 中生成 CSR,web 中的样本通常使用 package
sun.*
或 BouncyCastle 库。 It seems like there isn't a way to generate a CSR with the standard java.security
API. I read this and it seems to say the same thing.似乎没有办法使用标准
java.security
API 生成 CSR。我读了这篇文章,它似乎在说同样的话。
Do I have no choice but to use BouncyCastle?我别无选择,只能使用 BouncyCastle 吗? It is hard to imagine that Android Developers don't consider this kind of usage.
很难想象 Android 开发者不会考虑这种用法。
By the way, the article also mentions that:顺便说一句,文章还提到:
Generating a new PrivateKey requires that you also specify the initial X.509 attributes that the self-signed certificate will have.
生成新的私钥还需要您指定自签名证书将具有的初始 X.509 属性。 You can replace the certificate at a later time with a certificate signed by a Certificate Authority
您可以稍后将证书替换为由证书颁发机构签名的证书
Suppose I finally get a certificate signed by a Certificate Authority.假设我最终获得了由证书颁发机构签名的证书。 What exactly should I do to "replace the certificate at a later time"?
我究竟应该怎么做才能“稍后更换证书”?
Regarding generating a CSR (certificate sign request) on the android phone, I think it is rather straightforward to use Spongycastle instead.关于在 android 手机上生成 CSR(证书签名请求),我认为使用Spongycastle是相当简单的。 It is an android port of Bouncycastle.
它是 Bouncycastle 的 android 端口。
Suppose I finally get certificate signed by a Certificate Authority.
假设我最终获得了证书颁发机构签署的证书。 What exactly should I do to "replace the certificate at a later time"?
我究竟应该怎么做才能“稍后更换证书”?
Once you have the actual signed certificate which you are supposed to get from the CA (Certificate Authority), you no longer need your CSR;一旦您拥有应该从 CA(证书颁发机构)获得的实际签名证书,您就不再需要您的 CSR; you should just store the signed certificate on the phone.
您应该将签名证书存储在手机上。 Where to save them - I guess you can get help here .
在哪里保存它们 - 我想你可以在这里得到帮助。
The best way to create a CSR on Android is to use SpongyCastle , which is an implementation of BouncyCastle for Android.在 Android 上创建 CSR 的最佳方法是使用SpongyCastle ,它是适用于 Android 的BouncyCastle的实现。 SpongyCastle already does a lot of the heavy-lifting for you so it will make your life much easier.
SpongyCastle 已经为你做了很多繁重的工作,所以它会让你的生活更轻松。
My implementation is heavily based on the answer found here , but uses the Android KeyStore for security and SpongyCastle's JcaContentSignerBuilder()
instead of the custom ContentSigner
.我的实现在很大程度上基于这里找到的答案,但使用 Android KeyStore 来确保安全性和 SpongyCastle 的
JcaContentSignerBuilder()
而不是自定义ContentSigner
。
build.gradle
file:build.gradle
文件中:compile 'com.madgag.spongycastle:core:1.51.0.0'
compile 'com.madgag.spongycastle:pkix:1.51.0.0'
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();
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;
}
}
And that's it, now you have a PKCS10CertificationRequest
that you can send to your server.就是这样,现在您有一个
PKCS10CertificationRequest
可以发送到您的服务器。
You can use the Bouncy Castle to work with the keys from Android KeyStore.您可以使用 Bouncy Castle 来处理 Android KeyStore 中的密钥。 This doesn't mean that you have to set the Bouncy Castle as a security provider.
这并不意味着您必须将 Bouncy Castle 设置为安全提供程序。 It is enough to include the library:
包含库就足够了:
implementation 'org.bouncycastle:bcpkix-jdk18on:1.72'
Note: Spongy Castle is obsolete.注意:海绵城堡已过时。 Standard Bouncy Castle library has to be included in your Android application.
标准的 Bouncy Castle 库必须包含在您的 Android 应用程序中。 For details on why see: https://github.com/rtyley/spongycastle/issues/34
详细原因见: https://github.com/rtyley/spongycastle/issues/34
val keyPairGenerator: KeyPairGenerator = KeyPairGenerator.getInstance(
KeyProperties.KEY_ALGORITHM_EC,
"AndroidKeyStore"
)
val keySpecBuilder = KeyGenParameterSpec.Builder(
Constants.clientCertificateKeyAlias,
KeyProperties.PURPOSE_SIGN or KeyProperties.PURPOSE_VERIFY
).setDigests(KeyProperties.DIGEST_NONE, KeyProperties.DIGEST_SHA256, KeyProperties.DIGEST_SHA512)
keyPairGenerator.initialize(keySpecBuilder.build())
val pair = keyPairGenerator.generateKeyPair()
val p10Builder: PKCS10CertificationRequestBuilder = JcaPKCS10CertificationRequestBuilder(
X500Principal("CN=My Client Certificate"), pair.public
)
val csBuilder = JcaContentSignerBuilder("SHA256withECDSA")
val signer: ContentSigner = csBuilder.build(pair.private)
val csr: PKCS10CertificationRequest = p10Builder.build(signer)
val pemObject = PemObject("CERTIFICATE REQUEST", csr.encoded)
val csrAsString = csrAsStringingWriter()
val pemWriter = PEMWriter(csrAsString)
pemWriter.writeObject(pemObject)
pemWriter.close()
csrAsString.close()
Log.v("CSR", "CSR: $csrAsString")
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.