Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Convert PKCS10CertificationRequest to X509 certificate

I wonder if it is possible to convert a PKCS10CertificationRequest into a X509 Certificate using Bouncy Castle?

Similar to X509_REQ_to_X509 in openssl.

This is how I create the request:

public static PKCS10CertificationRequest generateCSRFile(KeyPair keyPair, KeyUsage keyUsage) throws IOException, OperatorCreationException {
    String principal = "CA=" getCA();

    AsymmetricKeyParameter privateKey = PrivateKeyFactory.createKey(keyPair.getPrivate().getEncoded());
    AlgorithmIdentifier signatureAlgorithm = new DefaultSignatureAlgorithmIdentifierFinder().find("SHA1WITHRSA");
    AlgorithmIdentifier digestAlgorithm = new DefaultDigestAlgorithmIdentifierFinder().find("SHA-1");
    ContentSigner signer = new BcRSAContentSignerBuilder(signatureAlgorithm, digestAlgorithm).build(privateKey);

    PKCS10CertificationRequestBuilder csrBuilder = new JcaPKCS10CertificationRequestBuilder(new X500Name(principal), keyPair.getPublic());
    ExtensionsGenerator extensionsGenerator = new ExtensionsGenerator();
    extensionsGenerator.addExtension(X509Extension.basicConstraints, true, new BasicConstraints(true));
    extensionsGenerator.addExtension(X509Extension.keyUsage, true, keyUsage);
    csrBuilder.addAttribute(PKCSObjectIdentifiers.x509Certificate, extensionsGenerator.generate());
    PKCS10CertificationRequest csr = csrBuilder.build(signer);
    return csr;
}
like image 808
Henric Avatar asked Sep 16 '25 00:09

Henric


1 Answers

I'm far from being an OpenSSL specialist but according to some documentation I found:

X509_REQ_to_X509(X509_REQ *r, int days, EVP_PKEY *pkey) creates an X509 certificate with subject and issuer the same as the subject in the request r, with validity days, and pkey used to sign it (with md5 as the digest).

Here is an equivalent with Bouncycastle:

public X509Certificate x509ReqToX509(PKCS10CertificationRequest csr, int days, PrivateKey pKey) 
{
  Date notBefore = new Date();
  Calendar cal = Calendar.getInstance();
  cal.add(Calendar.DATE, days);
  Date notAfter = cal.getTime();
  BigInteger serialNumber = generateCertSerialNumber(); // No implemented here

  X509V3CertificateGenerator certGen = new X509V3CertificateGenerator();

  certGen.setSerialNumber(serialNumber);
  certGen.setIssuerDN(csr.getCertificationRequestInfo().getSubject());
  certGen.setSubjectDN(csr.getCertificationRequestInfo().getSubject());
  certGen.setNotBefore(notBefore);
  certGen.setNotAfter(notAfter);
  certGen.setPublicKey(csr.getPublicKey());
  certGen.setSignatureAlgorithm("SHA256WithRSAEncryption");

  return certGen.generate(pKey, "BC");
}

Note that:

  1. I replaced MD5 by SHA-256 in the signature algorithm.
  2. Depending on the certificate aim this short code sample may need some update (for instance, adding some mandatory extension)
like image 127
Jcs Avatar answered Sep 17 '25 13:09

Jcs