Как создать CSR на Java, не подписывая его запрашивающей стороной?

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

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


person penguin4hire    schedule 17.11.2011    source источник


Ответы (2)


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

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);
    }

}
person Desphilboy    schedule 20.05.2014
comment
Принимаю ваш ответ, так как вы смогли предоставить пример кода. Спасибо! - person penguin4hire; 15.06.2014
comment
Похоже, эта работа почти дословно повторена здесь: journaldev.com/223/ - person Brian; 21.07.2017
comment
Пожалуйста, проявите должную осмотрительность, прежде чем обвинять кого-то в копировании материалов. Мой пост 2011 года, скопирован оттуда сюда. Вы можете проверить себя в обратном пути. web.archive.org/web*/journaldev.com/223/ - person Pankaj; 21.07.2017
comment
Что ж, я использовал материалы из журнала Journaldev и сохранил подпись журнала, чтобы было понятно (пожалуйста, смотрите в нижней строке). в любом случае, я не копировал и не вставлял, так как это было частью разработки в реальном мире, просто посолил и поперчил, чтобы сделать его общим. - person Desphilboy; 25.07.2017
comment
Я попробовал этот код, он отлично работает, большое спасибо, но сонар выдает ошибку, поскольку удалите это использование конструктора для вашего кода new PrintStream (bs);. Помогите пожалуйста, есть альтернатива? - person SurendraKumar Jaiswal; 15.06.2020
comment
@SurendraKumarJaiswal, извините, это код 7-летней давности, и он довольно запутанный, на самом деле я думаю, что ваш сонарный куб в этом случае прав, поскольку ps не используется для генерации вывода. вы можете использовать ps для создания журнала или просто удалить ps и все его ссылки в коде и записать непосредственно в bs или просто использовать другой тип потока. - person Desphilboy; 19.06.2020

Я использовал библиотеки 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}));
    
person penguin4hire    schedule 16.07.2012