使用多个密钥生成CSR PKCS#10

时间:2017-09-28 06:52:15

标签: java security cryptography bouncycastle pki

我刚开始研究PKI概念,下面我的解释有什么不妥,请原谅。

要求是向注册机构(RA)生成CSR(PKCS#10)请求,其中CSR将使用两个密钥(子密钥和主密钥)进行签名。后来RA验证请求并使用自己的证书,签名并向CA发送请求。

使用具有ECDSA算法的弹力城堡API生成密钥。甚至生成的PKCS#10 CSR(来自下面的程序)现在用子键签名。如下面的代码所示。

但下面的程序只使用子密钥签名,我需要知道如何再次签署整个PKCS#10 CSR或使用主密钥签署PKCS#7并将整个包发送给RA以便从CA在RA中进行了一些验证检查。

Bouncy caste maven version org.bouncycastle:1.56

import org.bouncycastle.asn1.ASN1ObjectIdentifier;
import org.bouncycastle.asn1.x500.RDN;
import org.bouncycastle.asn1.x500.X500Name;
import org.bouncycastle.asn1.x500.style.BCStyle;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.operator.ContentSigner;
import org.bouncycastle.operator.ContentVerifierProvider;
import org.bouncycastle.operator.OperatorCreationException;
import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
import org.bouncycastle.operator.jcajce.JcaContentVerifierProviderBuilder;
import org.bouncycastle.pkcs.PKCS10CertificationRequest;
import org.bouncycastle.pkcs.PKCS10CertificationRequestBuilder;
import org.bouncycastle.pkcs.PKCSException;
import org.bouncycastle.pkcs.jcajce.JcaPKCS10CertificationRequestBuilder;

import java.io.*;
import java.security.*;
import java.security.spec.ECGenParameterSpec;

public class BouncyCastleTest {
    static {
        Security.addProvider(new BouncyCastleProvider());
    }

    private static final String PROVIDER = "BC";
    private static final String ALGORITHM = "ECDSA";
    private static final String SIGNING_ALGORITHM = "SHA256withECDSA";

    public static void main(String[] args) throws IOException {

        BouncyCastleTest bcObject = new BouncyCastleTest();

        //1. Generate Key pair for Main and Sub keys
        KeyPair subKeyPair = bcObject.generateKeyPair("secp256r1");
        KeyPair mainKeyPair = bcObject.generateKeyPair("secp384r1");

        //2. Generate PKCS 10 request and sign with subKeyPair
        PKCS10CertificationRequest csrRequest = generatePKCS10Request(subKeyPair);

        //3. TODO sign the entire pkcs#10 message with main key?

        //4. read the content of the PKCS #10 CSR request
        readCSR(csrRequest);
    }

    private static PKCS10CertificationRequest generatePKCS10Request(KeyPair keyPair) {
        System.out.println("--- GENERATE PKCS#10 Format CSR ---");
        PKCS10CertificationRequest certRequest = null;
        ContentSigner signGen;

        //TODO Check for how to sign the CSR with MAIN keys
        //TODO some more attributes/values adding to CSR (Ex: port, serial num, destination, typeId etc)
        try {
            //Generating signature with sub private key
            signGen = new JcaContentSignerBuilder(SIGNING_ALGORITHM).build(keyPair.getPrivate());

            X500Name issuerDetails = new org.bouncycastle.asn1.x500.X500Name("CN=127.0.0.1, O=FOO, L=BAR, ST=BAZ, C=QUX");

            //sign the PKCS10 request add the sub public key to the message
            PKCS10CertificationRequestBuilder csrP10Builder = new JcaPKCS10CertificationRequestBuilder(issuerDetails, keyPair.getPublic());

            certRequest = csrP10Builder.build(signGen);

            System.out.println("--- GENERATED PKCS#10 Format CSR ---");
        } catch (OperatorCreationException e) {
            e.printStackTrace();
        }
        return certRequest;
    }

    private KeyPair generateKeyPair(String specification) {
        try {
            KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(ALGORITHM, PROVIDER);
            ECGenParameterSpec spec = new ECGenParameterSpec(specification);
            keyPairGen.initialize(spec);

            return keyPairGen.generateKeyPair();
        } catch (NoSuchAlgorithmException | NoSuchProviderException | InvalidAlgorithmParameterException e) {
            e.printStackTrace();
        }
        return null;
    }

    private static void readCSR(PKCS10CertificationRequest csr) {

        System.out.println("--- READ PKCS#10 Format CSR ---");
        try {
            //Validate the signature of the CSR
            ContentVerifierProvider verifierProvider = new JcaContentVerifierProviderBuilder().setProvider(PROVIDER).build(csr.getSubjectPublicKeyInfo());

            if(csr.isSignatureValid(verifierProvider)) {
                System.out.println("\n-- SIGNATURE VERIFIED ---");

                X500Name x500Name = csr.getSubject();
                System.out.println("x500Name is: "  + x500Name + "\n");

                System.out.println("Common name: "  + getX500Field(BCStyle.CN, x500Name));
                System.out.println("Organization: " + getX500Field(BCStyle.O, x500Name));
                System.out.println("Country: "      + getX500Field(BCStyle.C, x500Name));
                System.out.println("State: "         + getX500Field(BCStyle.ST, x500Name));

                //TODO read attributes/values added to CSR (Ex: port, serial num, destination, typeId etc)
            } else {
                System.out.println("-- INVALID SIGNATURE ---");
            }
        } catch (OperatorCreationException | PKCSException e) {
            e.printStackTrace();
        }
    }


    private static String getX500Field(ASN1ObjectIdentifier asn1ObjectIdentifier, X500Name x500Name) {
        RDN[] rdnArray = x500Name.getRDNs(asn1ObjectIdentifier);
        String retVal = null;
        for (RDN item : rdnArray) {
            retVal = item.getFirst().getValue().toString();
        }
        return retVal;
    }
}

我有以下需要实施的任务,需要了解如何完成这些任务。在程序中,您可以找到那些作为TODO任务。 1)检查如何签署/生成由MAIN密钥签名的CSR。 2)需要为PKCS#10 CSR添加更多属性/值(例如:端口,序列号,目标,类型等)

但主要部分是我们如何通过签署多个密钥来生成CSR?还有其他方法可以修复吗?

0 个答案:

没有答案