Last active
August 28, 2023 13:56
-
-
Save dopoljak/e7550dd0c01a3438c24c to your computer and use it in GitHub Desktop.
Example how to create PKCS#10 Certificate Signing Request (CSR) using Sun JDK, This example creates signature externally - suitable for Cryptographic devices such as Hardware Security Module (HSM)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.ilirium.client; | |
import java.io.ByteArrayOutputStream; | |
import java.io.FileNotFoundException; | |
import java.io.FileOutputStream; | |
import java.io.IOException; | |
import java.io.PrintStream; | |
import java.math.BigInteger; | |
import java.security.InvalidKeyException; | |
import java.security.KeyPair; | |
import java.security.KeyPairGenerator; | |
import java.security.NoSuchAlgorithmException; | |
import java.security.PublicKey; | |
import java.security.SecureRandom; | |
import java.security.Signature; | |
import java.security.SignatureException; | |
import java.util.Base64; | |
import sun.security.util.DerOutputStream; | |
import sun.security.x509.AlgorithmId; | |
import sun.security.x509.X500Name; | |
/** | |
* | |
* @author [email protected] | |
*/ | |
public class CertificateSigningRequestUsingSunJDK { | |
public static void main(String[] args) throws NoSuchAlgorithmException, IOException, InvalidKeyException, SignatureException { | |
// generate RSA key pair | |
KeyPair keypair = generateKeyPair(); | |
// create Certficate Request Info | |
X500Name x500Name = new X500Name("CN=Test,OU=Test,O=Test,L=Test,S=Test,C=Test"); | |
byte[] certReqInfo = createCertificationRequestInfo(x500Name, keypair.getPublic()); | |
// generate Signature over Certficate Request Info | |
String algorithm = "SHA1WithRSA"; | |
Signature signature = Signature.getInstance(algorithm); | |
signature.initSign(keypair.getPrivate()); | |
signature.update(certReqInfo); | |
byte[] certReqInfoSignature = signature.sign(); | |
// create PKCS#10 Certificate Signing Request (CSR) | |
byte[] csrDEREncoded = createCertificationRequestValue(certReqInfo, algorithm, certReqInfoSignature); | |
String csrPEMEncoded = createPEMFormat(csrDEREncoded); | |
// write to file | |
writeToFile(csrDEREncoded, "D:\\csr.der"); | |
writeToFile(csrPEMEncoded.getBytes(), "D:\\csr.pem"); | |
} | |
private static KeyPair generateKeyPair() throws NoSuchAlgorithmException { | |
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA"); | |
keyGen.initialize(2048, new SecureRandom()); | |
KeyPair keypair = keyGen.generateKeyPair(); | |
return keypair; | |
} | |
public static String createPEMFormat(byte[] data) { | |
final ByteArrayOutputStream out = new ByteArrayOutputStream(); | |
final PrintStream ps = new PrintStream(out); | |
ps.println("-----BEGIN NEW CERTIFICATE REQUEST-----"); | |
ps.println(Base64.getMimeEncoder().encodeToString(data)); | |
ps.println("-----END NEW CERTIFICATE REQUEST-----"); | |
return out.toString(); | |
} | |
public static byte[] createCertificationRequestInfo(X500Name x500Name, PublicKey publicKey) throws IOException { | |
final DerOutputStream der1 = new DerOutputStream(); | |
der1.putInteger(BigInteger.ZERO); | |
x500Name.encode(der1); | |
der1.write(publicKey.getEncoded()); | |
// der encoded certificate request info | |
final DerOutputStream der2 = new DerOutputStream(); | |
der2.write((byte) 48, der1); | |
return der2.toByteArray(); | |
} | |
public static byte[] createCertificationRequestValue(byte[] certReqInfo, String signAlgo, byte[] signature) throws IOException, NoSuchAlgorithmException { | |
final DerOutputStream der1 = new DerOutputStream(); | |
der1.write(certReqInfo); | |
// add signature algorithm identifier, and a digital signature on the certification request information | |
AlgorithmId.get(signAlgo).encode(der1); | |
der1.putBitString(signature); | |
// final DER encoded output | |
final DerOutputStream der2 = new DerOutputStream(); | |
der2.write((byte) 48, der1); | |
return der2.toByteArray(); | |
} | |
private static void writeToFile(byte[] data, String file) throws FileNotFoundException, IOException { | |
try (FileOutputStream out = new FileOutputStream(file)) { | |
out.write(data); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
It may be possible to add the type of certificate and SAN to the CSR
X509v3 Extended Key Usage: TLS Web Server Authentication, TLS Web Client Authentication