Generating CSR using Java and BouncyCastle API
updated on : 2013-10-22
source code in github : https://github.com/senthadev/programs/blob/master/GenerateCSR.java
This note is about generating CSR (Certificate Signing Request using PKCS#10 specification) programmatically
based on Java version “1.6.0_51” and BouncyCastle API “1.49”.
What is CSR?
According to wiki,
In public key infrastructure (PKI) systems, a certificate signing request (also CSR or certification request) is a message sent from an applicant to a certificate authority (CA) in order to apply for a digital identity certificate. The most common format for CSRs is the PKCS#10 specification.
Lets look at a scenario,
Applicant, Olav, wants to send a message to another applicant called Petter through internet. Now, Petter has to be confident that the message received from Olav is genuine and vice versa. One way to achieve this is by using the PKI. So, both of them will generate a key pair, private key and public key. Public keys are shared openly and the shared message is encrypted using their respective private keys. How will both of them share their public keys? using a third party called Certification Authority (CA) who is responsible to authenticate the users by signing their public keys. To get sign, Olav has to submit his public key to CA and this process is called CSR.
Lets get to the coding:
First, get the BouncyCastly library. I use maven to download them.
<dependency> <groupId>org.bouncycastle</groupId> <artifactId>bcprov-jdk15on</artifactId> <version>1.49</version> </dependency> <dependency> <groupId>org.bouncycastle</groupId> <artifactId>bcpkix-jdk15on</artifactId> <version>1.49</version> </dependency>
There are 3 ways to load the BouncyCastle security provider. They are
Static approach by updating the JRE_DIR/lib/security/java.security file.
Append : security.provider.1=org.bouncycastle.jce.provider.BouncyCastleProvider
Dynamically when the program initialized: (I use this approach)
Provider bc = new org.bouncycastle.jce.provider.BouncyCastleProvider();
Directly passing the provider object to the method calls.
Generate a keyPair, using RSA algorithm, which consists of Public key and a Private key. These keys are 2048 bit in size.
KeyPairGenerator gen = KeyPairGenerator.getInstance("RSA"); gen.initialize(2048); KeyPair pair = gen.generateKeyPair(); PrivateKey privateKey = pair.getPrivate(); PublicKey publicKey = pair.getPublic();
Create a “Distinguished Name” for the certificate. Generally its contains information about the company.
//import javax.security.auth.x500.X500Principal X500Principal subject = new X500Principal ("C=NO, ST=Trondheim, L=Trondheim, O=Senthadev, OU=Innovation, CN=www.senthadev.com, EMAILADDRESSfirstname.lastname@example.org");
Create a ContentSigner object using helper object org.bouncycastle.operator.jcajce.JcaContentSignerBuilder
Signer object is created using privateKey and “SHA1withRSA” algorithm.
//import org.bouncycastle.operator.ContentSigner ContentSigner signGen = new JcaContentSignerBuilder("SHA1withRSA").build(privateKey);
Now we can create the CSR.
//import org.bouncycastle.pkcs.PKCS10CertificationRequest; //import org.bouncycastle.pkcs.PKCS10CertificationRequestBuilder; //import org.bouncycastle.pkcs.jcajce.JcaPKCS10CertificationRequestBuilder; PKCS10CertificationRequestBuilder builder = new JcaPKCS10CertificationRequestBuilder(subject, publicKey); PKCS10CertificationRequest csr = builder.build(signGen);
If you want to print/write to a file in openssl PEM format,
//import org.bouncycastle.openssl.PEMWriter; OutputStreamWriter output = new OutputStreamWriter(System.out); PEMWriter pem = new PEMWriter(output); pem.writeObject(request); pem.close();