Как вы генерируете CSR в Java, не подписывая его запрашивающей стороной? - PullRequest
4 голосов
/ 17 ноября 2011

По сути, мне нужно изолировать данные построенного CSR (запроса на подпись сертификата) до того, как он будет сначала подписан объектом, выполняющим запрос, предпочтительно в Java.Заранее большое спасибо!

Также было бы полезно отметить, как впоследствии добавить подпись к CSR, поскольку данные CSR будут первоначально подписаны HSM.

Ответы [ 2 ]

7 голосов
/ 20 мая 2014

Надеюсь, это поможет:

import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.SecureRandom;
import java.security.Signature;


import javax.security.auth.x500.X500Principal;

import sun.security.pkcs10.*;
import sun.security.x509.*;

public class GenerateCSR {
    private static PublicKey publicKey = null;
    private static PrivateKey privateKey = null;
    private static KeyPairGenerator keyGen = null;
    private static GenerateCSR gcsr = null;

    private GenerateCSR() {
        try {
            keyGen = KeyPairGenerator.getInstance("RSA");
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        keyGen.initialize(2048, new SecureRandom());
        KeyPair keypair = keyGen.generateKeyPair();
        publicKey = keypair.getPublic();
        privateKey = keypair.getPrivate();
    }

    public static GenerateCSR getInstance() {
        if (gcsr == null)
            gcsr = new GenerateCSR();
        return gcsr;
    }

    public String getCSR(String cn) throws Exception {
        byte[] csr = generatePKCS10(cn, "Java", "JournalDev", "Cupertino",
                "California", "USA");
        return new String(csr);
    }

    /**
     *
     * @param CN
     *            Common Name, is X.509 speak for the name that distinguishes
     *            the Certificate best, and ties it to your Organization
     * @param OU
     *            Organizational unit
     * @param O
     *            Organization NAME
     * @param L
     *            Location
     * @param S
     *            State
     * @param C
     *            Country
     * @return
     * @throws Exception
     */
    private static byte[] generatePKCS10(String CN, String OU, String O,
            String L, String S, String C) throws Exception {
        // generate PKCS10 certificate request
        String sigAlg = "MD5WithRSA";
        PKCS10 pkcs10 = new PKCS10(publicKey);
        Signature signature = Signature.getInstance(sigAlg);
        signature.initSign(privateKey);
        // common, orgUnit, org, locality, state, country
        X500Principal principal = new X500Principal( "CN=Ole Nordmann, OU=ACME, O=Sales, C=NO");

   //     pkcs10CertificationRequest kpGen = new PKCS10CertificationRequest(sigAlg, principal, publicKey, null, privateKey);  
     //   byte[] c = kpGen.getEncoded();  
        X500Name x500name=null;
        x500name= new X500Name(principal.getEncoded());
      pkcs10.encodeAndSign(x500name, signature);
        ByteArrayOutputStream bs = new ByteArrayOutputStream();
        PrintStream ps = new PrintStream(bs);
        pkcs10.print(ps);
        byte[] c = bs.toByteArray();
        try {
            if (ps != null)
                ps.close();
            if (bs != null)
                bs.close();
        } catch (Throwable th) {
        }
        return c;
    }

    public PublicKey getPublicKey() {
        return publicKey;
    }

    public PrivateKey getPrivateKey() {
        return privateKey;
    }

    public static void main(String[] args) throws Exception {
        GenerateCSR gcsr = GenerateCSR.getInstance();

        System.out.println("Public Key:\n"+gcsr.getPublicKey().toString());

        System.out.println("Private Key:\n"+gcsr.getPrivateKey().toString());
        String csr = gcsr.getCSR("journaldev.com <http://www.journaldev.com>");
        System.out.println("CSR Request Generated!!");
        System.out.println(csr);
    }

}
1 голос
/ 16 июля 2012

Я использовал библиотеки Bouncy Castle для создания запроса на сертификат, не подписывая его. Проблема, с которой я столкнулся, заключалась в том, что многие приложения, доступные для создания CSR, позаботились как о его создании, так и о его подписании. Я только хотел произвести неподписанный CSR. К сожалению, я не могу разглашать код, используемый для создания неподписанного CSR из-за политики компании, но я перечислил много подсказок ниже, которые должны помочь другим. Вот некоторые шаги, которые могут помочь кому-то еще, пытающемуся сделать то же самое:

  1. Посмотрите на пример данных CSR, сгенерированных с помощью openssl или другого инструмента, используя следующий веб-сайт.

    http://lapo.it/asn1js/

    Этот сайт даже содержит пример объекта сертификата, чтобы увидеть его в действии.

  2. Ознакомьтесь с кодировкой ASN1. Вот как кодируются данные сертификата, и вам нужно будет аналогично кодировать CSR, используя Bouncy Castle.

  3. Используйте Bouncy Castle для получения данных CSR. Вот фрагмент кода для инициализации некоторых полей, обычно встречающихся в данных CSR.

    // Create Organization Name<br/>
    DERObjectIdentifier oidOrgName     = new DERObjectIdentifier("2.5.4.10");
    DERPrintableString  prntstrOrgName = new DERPrintableString("Test Organization");
    DERSet              setOrgName     = new DERSet(new DERSequence(new ASN1Encodable[] {oidOrgName, prntstrOrgName}));
    
    // Create org unit name
    DERObjectIdentifier oidOrgUnitName     = new DERObjectIdentifier(2.5.4.11);
    DERPrintableString  prntstrOrgUnitName = new DERPrintableString("Org Unit Name");
    DERSet              setOrgUnitName     = new DERSet(new DERSequence(new ASN1Encodable[] {oidOrgUnitName, prntstrOrgUnitName}));
    
...