【问题标题】:How do you generate a CSR in Java without signing it by the requester?如何在 Java 中生成 CSR 而无需请求者签名?
【发布时间】:2011-11-17 00:20:10
【问题描述】:

基本上,我需要先隔离构造的 CSR(证书签名请求)的数据,然后再由发出请求的实体签名,最好是在 Java 中。非常感谢!

注意如何随后将签名附加到 CSR 也很有用,因为 CSR 数据最初将由 HSM 签名。

【问题讨论】:

    标签: java certificate asn.1 csr


    【解决方案1】:

    我希望这会有所帮助:

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

    【讨论】:

    • 接受您的回答,因为您能够提供代码示例。谢谢!
    • 看起来这项工作在这里几乎逐字重复:journaldev.com/223/…
    • 在指责他人抄袭之前,请先进行尽职调查。我的帖子是 2011 年的,它是从那里复制到这里的。您可以在 Wayback 机器上检查自己。 web.archive.org/web*/journaldev.com/223/…
    • 好吧,我使用了 journaldev 的材料,并保留了 journaldev 的签名以明确这一点(请参阅底线)。无论如何,我没有复制粘贴,因为它是真实世界开发的一部分,只是在上面撒了点胡椒粉以使其通用。
    • 我试过这段代码,非常感谢,它运行良好,但声纳为您的代码“new PrintStream(bs);”给出错误为“删除构造函数的这种使用”。请帮帮我,还有其他选择吗?
    【解决方案2】:

    我使用 Bouncy Castle 库在未签名的情况下生成证书请求。我面临的问题是,许多可用于生成 CSR 的应用程序都负责生成它并对其进行签名。我只想制作一个未签名的 CSR。不幸的是,由于公司政策,我无法透露用于生成未签名 CSR 的代码,但我在下面列出了许多应该对其他人有所帮助的提示。以下是一些可能有助于其他人尝试做同样事情的步骤:

    1. 使用以下网站查看使用 openssl 或其他工具生成的示例 CSR 数据。

      http://lapo.it/asn1js/

      此站点甚至包含一个示例证书对象以查看它的运行情况。

    2. 熟悉 ASN1 编码。这就是证书数据的编码方式,您需要使用 Bouncy Castle 对 CSR 进行类似的编码。

    3. 使用 Bouncy Castle 生成 CSR 数据。这是一个代码 sn-p,用于初始化 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}));
      

    【讨论】:

      猜你喜欢
      • 2019-01-04
      • 1970-01-01
      • 1970-01-01
      • 2010-09-15
      • 2015-11-28
      • 2019-11-03
      • 1970-01-01
      • 1970-01-01
      • 2020-04-20
      相关资源
      最近更新 更多