인디노트

CSR (PKCS 10) 생성하는 Java Code Sample 본문

인증기술

CSR (PKCS 10) 생성하는 Java Code Sample

인디개발자 2018. 8. 21. 08:52
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)
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 dopoljak@gmail.com
 */
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);
        }
    }
}


반응형

'인증기술' 카테고리의 다른 글

Simple Certificate Enrolment Protocol  (0) 2018.08.22
SCEP 기술  (0) 2018.08.21
대칭키와 비대칭키  (0) 2018.08.06
이게 맞는 말인지 확인이 필요하다.  (0) 2018.08.03
Creating X.509 certificates programmatically in Java  (0) 2018.07.27
Comments