I cannot find any code/doc describing how to sign a CSR using BC. As input I have a CSR as a byte array and would like to get the cert in PEM and/or DER format.
I have gotten this far
def signCSR(csrData:Array[Byte], ca:CACertificate, caPassword:String) = { val csr = new PKCS10CertificationRequestHolder(csrData) val spi = csr.getSubjectPublicKeyInfo val ks = new java.security.spec.X509EncodedKeySpec(spi.getDEREncoded()) val kf = java.security.KeyFactory.getInstance("RSA") val pk = kf.generatePublic(ks) val (caCert, caPriv) = parsePKCS12(ca.pkcs12data, caPassword) val fromDate : java.util.Date = new java.util.Date // FixMe val toDate = fromDate // FixMe val issuer = PrincipalUtil.getIssuerX509Principal(caCert) val contentSigner = new JcaContentSignerBuilder("SHA256WithRSAEncryption").setProvider(BC).build(caPriv) val serial = BigInt(CertSerialnumber.nextSerialNumber) val certgen = new JcaX509v3CertificateBuilder(new X500Name(issuer.getName), serial.bigInteger, fromDate, toDate, csr.getSubject, pk)
I have trouble figuring out get from a certificate generator to store this in PEM or DER format.
Or am I going down the wrong path all together?
Ok ... I was looking to do the same stuff and for the life of me I couldn't figure out how. The APIs all talk about generating the key pairs and then generating the cert but not how to sign a CSR. Somehow, quite by chance - here's what I found.
Since PKCS10 represents the format of the request (of the CSR), you first need to put your CSR into a PKCS10Holder. Then, you pass it to a CertificateBuilder (since CertificateGenerator is deprecated). The way you pass it is to call getSubject on the holder.
Here's the code (Java, please adapt as you need):
public static X509Certificate sign(PKCS10CertificationRequest inputCSR, PrivateKey caPrivate, KeyPair pair) throws InvalidKeyException, NoSuchAlgorithmException, NoSuchProviderException, SignatureException, IOException, OperatorCreationException, CertificateException { AlgorithmIdentifier sigAlgId = new DefaultSignatureAlgorithmIdentifierFinder() .find("SHA1withRSA"); AlgorithmIdentifier digAlgId = new DefaultDigestAlgorithmIdentifierFinder() .find(sigAlgId); AsymmetricKeyParameter foo = PrivateKeyFactory.createKey(caPrivate .getEncoded()); SubjectPublicKeyInfo keyInfo = SubjectPublicKeyInfo.getInstance(pair .getPublic().getEncoded()); PKCS10CertificationRequestHolder pk10Holder = new PKCS10CertificationRequestHolder(inputCSR); //in newer version of BC such as 1.51, this is //PKCS10CertificationRequest pk10Holder = new PKCS10CertificationRequest(inputCSR); X509v3CertificateBuilder myCertificateGenerator = new X509v3CertificateBuilder( new X500Name("CN=issuer"), new BigInteger("1"), new Date( System.currentTimeMillis()), new Date( System.currentTimeMillis() + 30 * 365 * 24 * 60 * 60 * 1000), pk10Holder.getSubject(), keyInfo); ContentSigner sigGen = new BcRSAContentSignerBuilder(sigAlgId, digAlgId) .build(foo); X509CertificateHolder holder = myCertificateGenerator.build(sigGen); X509CertificateStructure eeX509CertificateStructure = holder.toASN1Structure(); //in newer version of BC such as 1.51, this is //org.spongycastle.asn1.x509.Certificate eeX509CertificateStructure = holder.toASN1Structure(); CertificateFactory cf = CertificateFactory.getInstance("X.509", "BC"); // Read Certificate InputStream is1 = new ByteArrayInputStream(eeX509CertificateStructure.getEncoded()); X509Certificate theCert = (X509Certificate) cf.generateCertificate(is1); is1.close(); return theCert; //return null; }
As you can see, I've generated the request outside this method, but passed it in. Then, I have the PKCS10CertificationRequestHolder to accept this as a constructor arg.
Next, in the X509v3CertificateBuilder arguments, you'll see the pk10Holder.getSubject - this is apparently all you need? If something is missing, please let me know too!!! It worked for me. The cert I generated correctly had the DN info I needed.
Wikipedia has a killer section on PKCS - http://en.wikipedia.org/wiki/PKCS
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With