如何使用 Java 创建 CSR 请求

问题描述

目前的情况是我们从USBKEY中拿到了公钥,但是我们需要使用私钥对CSR请求进行签名。我不知道该怎么做

image

红圈里面的数据是我们从USBKEY得到的公钥,但是kp.getPrivate()我觉得应该是错误的。

这是生成中国通用CSR的代码

<!-- language: lang-java -->
package com.xf.face.util;

import fisher.man.util.encoders.Base64;
import org.bouncycastle.asn1.x500.X500Name;
import org.bouncycastle.asn1.x500.X500NameBuilder;
import org.bouncycastle.asn1.x500.style.BCStyle;
import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
import org.bouncycastle.jce.interfaces.EcpublicKey;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.jce.provider.JCEEcpublicKey;
import org.bouncycastle.operator.ContentSigner;
import org.bouncycastle.operator.OperatorCreationException;
import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
import org.bouncycastle.pkcs.PKCS10CertificationRequest;
import org.bouncycastle.pkcs.PKCS10CertificationRequestBuilder;
import org.bouncycastle.pkcs.jcajce.JcaPKCS10CertificationRequestBuilder;
import sun.security.util.CurveDB;

import java.io.IOException;
import java.lang.reflect.Method;
import java.math.BigInteger;
import java.security.*;
import java.security.spec.ECGenParameterSpec;
import java.security.spec.ECPoint;
import java.util.regex.Pattern;

/**
 * @ Author     :焦康
 * @ Date       :Created in 9:35 2021/4/6
 * @ Description:国密证书csr请求
 */
public class SM2CsrUtil {


    //国密推荐256位曲线参数
    private static final String P_STR = "FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFF";
    private static final String A_STR = "FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFC";
    private static final String B_STR = "28E9FA9E9D9F5E344D5A9E4BCF6509A7F39789F515AB8F92DDBCBD414D940E93";
    private static final String N_STR = "FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFF7203DF6B21C6052B53BBF40939D54123";
    //base point
    private static final String X_STR = "32C4AE2C1F1981195F9904466A39C9948FE30BBFF2660BE1715A4589334C74C7";
    private static final String Y_STR = "BC3736A2F4F6779C59BDCEE36B692153D0A9877CC62A474002DF32E52139F0A0";
    private static final String SPLIT_PATTERN = ",|\\[|\\]";
    /**
     * 算法提供者 Bouncy Castle
     */
    private static final Provider BC = new BouncyCastleProvider();

    public static String genCSR(String subject,String alg,String provider,byte[] pkdata) throws NoSuchAlgorithmException,OperatorCreationException,InvalidAlgorithmParameterException,NoSuchProviderException {

        String signalg = "";
        int alglength = 0;
        String keyAlg = "";
        String hexString = null;
        if (alg.toupperCase().equals("RSA1024")) {
            signalg = "SHA1WithRSA";
            alglength = 1024;
            keyAlg = "RSA";
        } else if (alg.toupperCase().equals("RSA2048")) {
            // signalg = "SHA1WithRSA";
            signalg = "1.2.840.10045.4.1";
            alglength = 2048;
            keyAlg = "RSA";
        } else if (alg.toupperCase().equals("SM2")) {
            // signalg = "ECDSAWITHSHA1";
            signalg = "SM3withSM2";
            alglength = 256;
            keyAlg = "EC";
        }
        org.bouncycastle.jce.provider.BouncyCastleProvider bouncyCastleProvider = new org.bouncycastle.jce.provider.BouncyCastleProvider();
        Provider t[] = Security.getProviders();
        Security.addProvider(bouncyCastleProvider);
        Provider t1[] = Security.getProviders();
        KeyPairGenerator keyGen = KeyPairGenerator.getInstance(keyAlg,BC);
        keyGen.initialize(new ECGenParameterSpec("sm2p256v1"));
        KeyPair kp = keyGen.generateKeyPair();
        byte[] heradByte = new byte[]{48,89,48,19,6,7,42,-122,72,-50,61,2,1,8,3,66,4};
        byte[] data = byteMerger(heradByte,pkdata);

        PKCS10CertificationRequestBuilder builder = new PKCS10CertificationRequestBuilder(new X500Name(subject),SubjectPublicKeyInfo.getInstance(data));
        JcaContentSignerBuilder jcaContentSignerBuilder = new JcaContentSignerBuilder(signalg).setProvider("BC");
        ContentSigner contentSigner = jcaContentSignerBuilder.build(kp.getPrivate());
        PKCS10CertificationRequest Request = builder.build(contentSigner);
        try {
            byte[] encoded2 = Request.getEncoded();
            hexString = new String(Base64.encode(encoded2));
            System.out.println(hexString.replace("\r","").replace("\n",""));
        } catch (IOException e) {
            e.printstacktrace();
        }
        return hexString;
    }

    //System.arraycopy()方法
    public static byte[] byteMerger(byte[] bt1,byte[] bt2) {
        byte[] bt3 = new byte[bt1.length + bt2.length];
        System.arraycopy(bt1,bt3,bt1.length);
        System.arraycopy(bt2,bt1.length,bt2.length);
        return bt3;
    }




    public static void main(String[] args) throws OperatorCreationException,NoSuchAlgorithmException,NoSuchProviderException {
        try {
            //add sm2p256v1 support to EC CurveDB
            Pattern localPattern = Pattern.compile(SPLIT_PATTERN);
            Class[] argTypes = {
                    String.class,String.class,int.class,Pattern.class};
            Object[] argss = new Object[]{
                    "sm2p256v1","1.2.156.10197.1.301",P_STR,A_STR,B_STR,X_STR,Y_STR,N_STR,localPattern};
            Method add = CurveDB.class.getDeclaredMethod("add",argTypes);
            add.setAccessible(true);
            add.invoke(CurveDB.class,argss);
        } catch (Exception e) {
            throw new RuntimeException(e.getMessage(),e);
        }
        String dn = "CN=TEST";
        String pkStr = "AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAv/pInHHFzGAdhIRGDKOc2bjq9I3SUGIOIcMRwgMSpqEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIWXe67pEetAHBkEPY2Mi5B1TLu0+fH0z5gosfV21aUO";
        byte[] pkdata = Base64.decode(pkStr);
        byte[] x = new byte[32];
        byte[] y = new byte[32];
        System.arraycopy(pkdata,36,x,32);
        System.arraycopy(pkdata,36 + 32 + 32,y,32);
        byte[] data = byteMerger(x,y);
        String csr = genCSR(dn,"SM2","CA",data);
        System.out.println("生成的CSR:" + csr);
    }

}

解决方法

这个问题已经解决了。 CSR 应在 USBKEY 中生成。这个问题已经解决了