In the new version of Bouncy Castle library there are changes in PKCS10CertificationRequest
. In previous versions it was possible to get PublicKey
from such request using getPublicKey()
method (see old doc).
Now this method disappered. How can I get PublicKey from with from such request?
There is getSubjectPublicKeyInfo().parsePublicKey()
but it returns ASN1Primitive
.
I see that from SPKAC NetscapeCertRequest
I still can read PublicKey directly by calling getPublicKey()
.
There is a utility class in the main provider package called PublicKeyFactory. The method createKey returns an AsymmetricKeyParameter which you cast to whatever type of public key is appropriate, e.g.
SubjectPublicKeyInfo pkInfo = pkcs10CertReq.getSubjectPublicKeyInfo();
RSAKeyParameters rsa = (RSAKeyParameters) PublicKeyFactory.createKey(pkInfo);
EDIT 1:
In addition, to create a java.security.PublicKey
a few more steps are needed:
RSAPublicKeySpec rsaSpec = new RSAPublicKeySpec(rsa.getModulus(), rsa.getExponent());
KeyFactory kf = KeyFactory.getInstance("RSA");
PublicKey rsaPub = kf.generatePublic(rsaSpec);
I was looking at the same issue, and this will work too (with the advantage that we don't need to specify the algorithm):
SubjectPublicKeyInfo pkInfo = pkcs10CertReq.getSubjectPublicKeyInfo();
JcaPEMKeyConverter converter = new JcaPEMKeyConverter();
PublicKey pubKey = converter.getPublicKey(pkInfo);
See org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter
What about using JcaPKCS10CertificationRequest?
JcaPKCS10CertificationRequest jcaPKCS10CertificationRequest = new JcaPKCS10CertificationRequest(pkcs10CertReq);
PublicKey publicKey = jcaPKCS10CertificationRequest.getPublicKey();
PKCS10CertificationRequest csr =...;
PublicKey pk = KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(csr.getSubjectPublicKeyInfo().toASN1Primitive().getEncoded()));
RFC 2986 - PKCS #10: Certification Request Syntax
CertificationRequestInfo ::= SEQUENCE {
version INTEGER { v1(0) } (v1,...),
subject Name,
subjectPKInfo SubjectPublicKeyInfo{{ PKInfoAlgorithms }},
attributes [0] Attributes{{ CRIAttributes }}
}
SubjectPublicKeyInfo { ALGORITHM : IOSet} ::= SEQUENCE {
algorithm AlgorithmIdentifier {{IOSet}},
subjectPublicKey BIT STRING
}
and then, you can see the document of java.security.spec.X509EncodedKeySpec
SubjectPublicKeyInfo ::= SEQUENCE {
algorithm AlgorithmIdentifier,
subjectPublicKey BIT STRING }
so you will know the encoding of this public key is X.509. and then change it to X509EncodedKeySpec and generate public key by keyFactory