To get the public key signed, the subject first create a Certificate Signing Request (CSR), Which contains the public key and the details of the subject such as Distinguished Name (DN), Organization (O), Organization Unit (OU), State (ST), Country(C). The CA then verify these details and sign (or reject) the request.
If you are using Java to sign a certificate, you can use Bouncy Castle to sign the CSRs programmatically. Following code will explain how it can be done with bouncycastle 1.49.
In order to use bouncycastle, you need to add the bcprov and bcpkix jars to the classpath which can be downloaded from [1] and add the bouncycastle provider as,
Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
We'll begin by creating a PKCS10CertificationRequest object from the CSR
encodedCsr = "....." //The PEM encoded CSR's text content PEMParser pemParser = new PEMParser(new InputStreamReader(new ByteArrayInputStream(encodedCsr.getBytes()))); PKCS10CertificationRequest request = (PKCS10CertificationRequest) pemParser.readObject();
Then sign the above created PKCS10CertificationRequest as follows,
try { int validity = 365; //No of days the certificate should be valid String serialNo = ...; // a unique number privateKey = ...; // The CA's private key caCert = ...; //The CA's certificate as a X509Certificate Date issuedDate = new Date(); Date expiryDate = new Date(System.currentTimeMillis() + validity * MILLIS_PER_DAY); //MILLIS_PER_DAY=86400000l JcaPKCS10CertificationRequest jcaRequest = new JcaPKCS10CertificationRequest(request); X509v3CertificateBuilder certificateBuilder = new JcaX509v3CertificateBuilder(caCert, new BigInteger(serialNo), issuedDate, expiryDate, jcaRequest.getSubject(), jcaRequest.getPublicKey()); JcaX509ExtensionUtils extUtils = new JcaX509ExtensionUtils(); certificateBuilder.addExtension(Extension.authorityKeyIdentifier, false, extUtils.createAuthorityKeyIdentifier(caCert)) .addExtension(Extension.subjectKeyIdentifier, false, extUtils.createSubjectKeyIdentifier(jcaRequest .getPublicKey())) .addExtension(Extension.basicConstraints, true, new BasicConstraints(0)) .addExtension(Extension.keyUsage, true, new KeyUsage(KeyUsage.digitalSignature | KeyUsage .keyEncipherment)) .addExtension(Extension.extendedKeyUsage, true, new ExtendedKeyUsage(KeyPurposeId.id_kp_serverAuth)); ContentSigner signer = new JcaContentSignerBuilder("SHA1withRSA").setProvider("BC").build(privateKey); //Add the CRL endpoint DistributionPointName crlEp = new DistributionPointName(new GeneralNames(new GeneralName(GeneralName .uniformResourceIdentifier, CA_CRL_ENDPOINT_URL))); DistributionPoint disPoint = new DistributionPoint(crlEp, null, null); certificateBuilder.addExtension(Extension.cRLDistributionPoints, false, new CRLDistPoint(new DistributionPoint[]{disPoint})); //Add the OCSP endpoint AccessDescription ocsp = new AccessDescription(AccessDescription.id_ad_ocsp, new GeneralName(GeneralName.uniformResourceIdentifier, CA_OCSP_ENDPOINT_URL) ); ASN1EncodableVector authInfoAccessASN = new ASN1EncodableVector(); authInfoAccessASN.add(ocsp); certificateBuilder.addExtension(Extension.authorityInfoAccess, false, new DERSequence(authInfoAccessASN)); X509Certificate signedCert = new JcaX509CertificateConverter().setProvider("BC").getCertificate (certificateBuilder.build(signer)); } catch (Exception e) { throw new CaException("Error in signing the certificate", e); }
[1] https://www.bouncycastle.org/latest_releases.html
excellent post! thanks!
ReplyDeleteIt is my first visit to your blog, and I am very impressed with this article that you share. Give adequate knowledge for me. Thank you for sharing useful material.Bouncy Castle Rental Aylesbury
ReplyDelete