Create Unsigned PKCS10 Certification Request in Java using Bouncy Castle

| April 21, 2015 | Reply

Usually, when you create a CSR, you have to: generate a private/public key pair, create a PKCS10 CSR with the public key and a X500 Subject, sign the CSR with the private key. This is literally what the Java Crypto APIs and Bouncy Castle NEED to do if you want to get the encoded CSR. However if the private key is generated in a smartcard or some other kind of HSM and you can’t access the private key and can’t use any signing function unless there is an issued certificate, you will have to create an unsigned CSR.
This is what I had to do and it is completely possible using BouncyCastle. However, the solution is not obvious. After spending some time digging through the BC sources, I finally came up with this class:

public class UnsignedPkcs10CertificationRequest {

	private CertificationRequestInfo certificationRequestInfo;

	public UnsignedPkcs10CertificationRequest(CertificationRequestInfo certificationRequestInfo) {
		this.certificationRequestInfo = certificationRequestInfo;
	}
	
	public byte[] getEncoded() {
		try {
			ASN1EncodableVector v = new ASN1EncodableVector();
			v.add(certificationRequestInfo);
			ASN1ObjectIdentifier oid = new ASN1ObjectIdentifier("0.0");
			v.add(new DERSequence(oid));
			v.add(new DERBitString(new byte[] {}));
			byte[] encoded = new DERSequence(v).getEncoded();
			return encoded;
		} catch (IOException e) {
			throw new RuntimeException(e);
		}
	}
}

Long story short, if you want an unsigned CSR, you have to assemble it almost by yourself. Almost, because you can actually reuse the CertificationRequestInfo class.
How to use it:

X500Name x500 = new X500Name("CN=..."); //enter your DN here
CertificationRequestInfo csrInfo = new CertificationRequestInfo(x500, publicKeyInfo, new DERSet()); //you must instantiate publicKeyInfo beforehand
UnsignedPkcs10CertificationRequest pkcs10 = new UnsignedPkcs10CertificationRequest(csrInfo);

PublicKeyInfo can be constructed from a byte array. I had a previously created java.security.PublicKey and I used getEncoded() to get the bytes.

Tags: , , ,

Category: Development

About the Author ()

Leave a Reply