【问题标题】:Sign CSR using Bouncy Castle使用 Bouncy Castle 签署 CSR
【发布时间】:2011-08-29 12:52:32
【问题描述】:

我找不到任何描述如何使用 BC 签署 CSR 的代码/文档。作为输入,我有一个 CSR 作为字节数组,并希望获得 PEM 和/或 DER 格式的证书。

我已经走到这一步了

def signCSR(csrData:Array[Byte], ca:CACertificate, caPassword:String) = {
  val csr = new PKCS10CertificationRequestHolder(csrData)
  val spi = csr.getSubjectPublicKeyInfo

  val ks = new java.security.spec.X509EncodedKeySpec(spi.getDEREncoded())
  val kf = java.security.KeyFactory.getInstance("RSA")
  val pk = kf.generatePublic(ks)

  val (caCert, caPriv) = parsePKCS12(ca.pkcs12data, caPassword)

  val fromDate : java.util.Date = new java.util.Date // FixMe
  val toDate = fromDate // FixMe
  val issuer = PrincipalUtil.getIssuerX509Principal(caCert)
  val contentSigner = new JcaContentSignerBuilder("SHA256WithRSAEncryption").setProvider(BC).build(caPriv)
  val serial = BigInt(CertSerialnumber.nextSerialNumber)
  val certgen = new JcaX509v3CertificateBuilder(new X500Name(issuer.getName), serial.bigInteger, fromDate, toDate, csr.getSubject, pk)

我无法从证书生成器获取 get 以将其存储为 PEM 或 DER 格式。

还是我一起走错了路?

【问题讨论】:

    标签: java scala bouncycastle


    【解决方案1】:

    好吧......我一直在寻找做同样的事情,但对于我的生活,我不知道该怎么做。 API 都在讨论生成密钥对然后生成证书,而不是如何签署 CSR。不知何故,很偶然 - 这就是我发现的。

    由于 PKCS10 代表(CSR)请求的格式,您首先需要将您的 CSR 放入 PKCS10Holder。然后,将其传递给 CertificateBuilder(因为不推荐使用 CertificateGenerator)。您传递它的方式是在持有人上调用 getSubject 。

    这是代码(Java,请根据需要调整):

    public static X509Certificate sign(PKCS10CertificationRequest inputCSR, PrivateKey caPrivate, KeyPair pair)
            throws InvalidKeyException, NoSuchAlgorithmException,
            NoSuchProviderException, SignatureException, IOException,
            OperatorCreationException, CertificateException {   
    
        AlgorithmIdentifier sigAlgId = new DefaultSignatureAlgorithmIdentifierFinder()
                .find("SHA1withRSA");
        AlgorithmIdentifier digAlgId = new DefaultDigestAlgorithmIdentifierFinder()
                .find(sigAlgId);
    
        AsymmetricKeyParameter foo = PrivateKeyFactory.createKey(caPrivate
                .getEncoded());
        SubjectPublicKeyInfo keyInfo = SubjectPublicKeyInfo.getInstance(pair
                .getPublic().getEncoded());
    
        PKCS10CertificationRequestHolder pk10Holder = new PKCS10CertificationRequestHolder(inputCSR);
        //in newer version of BC such as 1.51, this is 
        //PKCS10CertificationRequest pk10Holder = new PKCS10CertificationRequest(inputCSR);
    
        X509v3CertificateBuilder myCertificateGenerator = new X509v3CertificateBuilder(
                new X500Name("CN=issuer"), new BigInteger("1"), new Date(
                        System.currentTimeMillis()), new Date(
                        System.currentTimeMillis() + 30 * 365 * 24 * 60 * 60
                                * 1000), pk10Holder.getSubject(), keyInfo);
    
        ContentSigner sigGen = new BcRSAContentSignerBuilder(sigAlgId, digAlgId)
                .build(foo);        
    
        X509CertificateHolder holder = myCertificateGenerator.build(sigGen);
        X509CertificateStructure eeX509CertificateStructure = holder.toASN1Structure(); 
        //in newer version of BC such as 1.51, this is 
        //org.spongycastle.asn1.x509.Certificate eeX509CertificateStructure = holder.toASN1Structure(); 
    
        CertificateFactory cf = CertificateFactory.getInstance("X.509", "BC");
    
        // Read Certificate
        InputStream is1 = new ByteArrayInputStream(eeX509CertificateStructure.getEncoded());
        X509Certificate theCert = (X509Certificate) cf.generateCertificate(is1);
        is1.close();
        return theCert;
        //return null;
    }
    

    如您所见,我在此方法之外生成了请求,但将其传入。然后,我让 PKCS10CertificationRequestHolder 接受它作为构造函数 arg。

    接下来,在 X509v3CertificateBuilder 参数中,您将看到 pk10Holder.getSubject - 这显然就是您所需要的?如果有什么遗漏也请告诉我!!!它对我有用。我正确生成的证书有我需要的 DN 信息。

    维基百科有一个关于 PKCS 的杀手级部分 - http://en.wikipedia.org/wiki/PKCS

    【讨论】:

    【解决方案2】:

    以下代码基于上述答案,但将编译,并在给定 PEM 编码的 CSR(由 keytool 导出的那种)的情况下,将返回一个有效的 PEM 编码的 signedData 对象,其中包含一个签名的证书链(类型为可以通过keytool导入)。

    哦,这是针对 BouncyCastle 1.49 的。

    import java.security.*;
    import java.io.*;
    import java.util.Date;
    import java.math.BigInteger;
    import java.security.cert.X509Certificate;
    import org.bouncycastle.asn1.x509.*;
    import org.bouncycastle.asn1.x500.*;
    import org.bouncycastle.asn1.pkcs.*;
    import org.bouncycastle.openssl.*;
    import org.bouncycastle.pkcs.*;
    import org.bouncycastle.cert.*;
    import org.bouncycastle.cms.*;
    import org.bouncycastle.cms.jcajce.*;
    import org.bouncycastle.crypto.util.*;
    import org.bouncycastle.operator.*;
    import org.bouncycastle.operator.bc.*;
    import org.bouncycastle.operator.jcajce.*;
    import org.bouncycastle.util.encoders.Base64;
    
    /**
     * Given a Keystore containing a private key and certificate and a Reader containing a PEM-encoded
     * Certificiate Signing Request (CSR), sign the CSR with that private key and return the signed
     * certificate as a PEM-encoded PKCS#7 signedData object. The returned value can be written to a file
     * and imported into a Java KeyStore with "keytool -import -trustcacerts -alias subjectalias -file file.pem"
     *
     * @param pemcsr a Reader from which will be read a PEM-encoded CSR (begins "-----BEGIN NEW CERTIFICATE REQUEST-----")
     * @param validity the number of days to sign the Certificate for
     * @param keystore the KeyStore containing the CA signing key
     * @param alias the alias of the CA signing key in the KeyStore
     * @param password the password of the CA signing key in the KeyStore
     *
     * @return a String containing the PEM-encoded signed Certificate (begins "-----BEGIN PKCS #7 SIGNED DATA-----")
     */
    public static String signCSR(Reader pemcsr, int validity, KeyStore keystore, String alias, char[] password) throws Exception {
        PrivateKey cakey = (PrivateKey)keystore.getKey(alias, password);
        X509Certificate cacert = (X509Certificate)keystore.getCertificate(alias);
        PEMReader reader = new PEMReader(pemcsr);
        PKCS10CertificationRequest csr = new PKCS10CertificationRequest((CertificationRequest)reader.readObject());
    
        AlgorithmIdentifier sigAlgId = new DefaultSignatureAlgorithmIdentifierFinder().find("SHA1withRSA");
        AlgorithmIdentifier digAlgId = new DefaultDigestAlgorithmIdentifierFinder().find(sigAlgId);
        X500Name issuer = new X500Name(cacert.getSubjectX500Principal().getName());
        BigInteger serial = new BigInteger(32, new SecureRandom());
        Date from = new Date();
        Date to = new Date(System.currentTimeMillis() + (validity * 86400000L));
    
        X509v3CertificateBuilder certgen = new X509v3CertificateBuilder(issuer, serial, from, to, csr.getSubject(), csr.getSubjectPublicKeyInfo());
        certgen.addExtension(X509Extension.basicConstraints, false, new BasicConstraints(false));
        certgen.addExtension(X509Extension.subjectKeyIdentifier, false, new SubjectKeyIdentifier(csr.getSubjectPublicKeyInfo()));
        certgen.addExtension(X509Extension.authorityKeyIdentifier, false, new AuthorityKeyIdentifier(new GeneralNames(new GeneralName(new X509Name(cacert.getSubjectX500Principal().getName()))), cacert.getSerialNumber()));
    
        ContentSigner signer = new BcRSAContentSignerBuilder(sigAlgId, digAlgId).build(PrivateKeyFactory.createKey(cakey.getEncoded()));
        X509CertificateHolder holder = certgen.build(signer);
        byte[] certencoded = holder.toASN1Structure().getEncoded();
    
        CMSSignedDataGenerator generator = new CMSSignedDataGenerator();
        signer = new JcaContentSignerBuilder("SHA1withRSA").build(cakey);
        generator.addSignerInfoGenerator(new JcaSignerInfoGeneratorBuilder(new JcaDigestCalculatorProviderBuilder().build()).build(signer, cacert));
        generator.addCertificate(new X509CertificateHolder(certencoded));
        generator.addCertificate(new X509CertificateHolder(cacert.getEncoded()));
        CMSTypedData content = new CMSProcessableByteArray(certencoded);
        CMSSignedData signeddata = generator.generate(content, true);
    
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        out.write("-----BEGIN PKCS #7 SIGNED DATA-----\n".getBytes("ISO-8859-1"));
        out.write(Base64.encode(signeddata.getEncoded()));
        out.write("\n-----END PKCS #7 SIGNED DATA-----\n".getBytes("ISO-8859-1"));
        out.close();
        return new String(out.toByteArray(), "ISO-8859-1");
    }
    

    【讨论】:

    • 你使用 Maven。如果是这样,请您分享您的 Maven xml。
    【解决方案3】:

    谢谢阿奇!

    我对你的代码做了一些修改,见下文。

    主要的变化是传递发行者的名字并使用来自 CSR 的公钥。

    val caCert = PEMToCert(issuerPEM).get
    val issuer = PrincipalUtil.getIssuerX509Principal(caCert)
    val csr = new PKCS10CertificationRequestHolder(csrData)
    val serial = BigInt(CertSerialNumber.nextSerialNumber)
    val spi = csr.getSubjectPublicKeyInfo();
    
    val certgen = new X509v3CertificateBuilder(
        new X500Name(issuer.getName),
        serial.bigInteger,
        new java.util.Date(),
        new Date(System.currentTimeMillis() + 30 * 365 * 24 * 60 * 60 * 1000),
        csr.getSubject,
        csr.getSubjectPublicKeyInfo())
    
    certgen.addExtension(
        X509Extension.subjectKeyIdentifier,
        false,
        spi
    )
    
    val issuerPK = PEMToPK(issuerPKPEM, caPassword).get
    val contentSigner = new JcaContentSignerBuilder(contentSignerAlg).setProvider(BC).build(issuerPK.getPrivate())
    val x509 = (new JcaX509CertificateConverter).setProvider(BC).getCertificate(certgen.build(contentSigner))
    

    【讨论】:

      【解决方案4】:

      @Mike B - 您是否彻底测试了您的示例?我的代码有一个奇怪的行为: 我使用的是 bc15on 版本。当我使用自签名 CA 签署客户端请求时,我将其导入 IE 并显示证书对链中的 CA 有效

      但是您可以看到,当在 FF 中导入右侧的图像时,链中的 CA 丢失并且 ff 无法向受信任的机构验证它。在尝试使用 IE 或 FF 向 Web 服务器进行身份验证时也会失败,因为 http 也无法将其验证给受信任的权威机构。

      我已经对您的代码进行了一些更改以满足我的需要,但总的来说它应该是相同的,谁能给我一些关于我在这里做错了什么的指示:

          public static String GenCert(long SerNum, int addYear, int addHours,
                                   String reqText,
                                   String reqName) throws Exception,
                                                          SQLException {
      
          String result = "";
          reqText = csr; // hard code base64 csr for testing purposes
          reqText =
              "-----BEGIN CERTIFICATE REQUEST-----\n" + reqText +
              "\n-----END CERTIFICATE REQUEST-----\n";
      
          try {
      
      
              String castr = ca + "\n"; // hard code base64 CA pub key for testing
              String strPriv = caPrivk + "\n"; // hard code base64 CA private key for testing
      
      
              byte[] encKey = castr.getBytes();
              CertificateFactory cf = CertificateFactory.getInstance("X.509");
              X509Certificate caCert =
                  (X509Certificate)cf.generateCertificate(new ByteArrayInputStream(encKey));
      
              PEMParser pr = new PEMParser(new StringReader(strPriv));
              Object obj = pr.readObject();
              JcaPEMKeyConverter converter =
                  new JcaPEMKeyConverter().setProvider("BC");
              KeyPair kp;
              kp = converter.getKeyPair((PEMKeyPair)obj);
      
              PrivateKey privateKey = kp.getPrivate();
      
              // parse the request
              PEMParser pRd =
                  new PEMParser(new InputStreamReader(new ByteArrayInputStream(reqText.getBytes())));
              PKCS10CertificationRequest csr =
                  (PKCS10CertificationRequest)pRd.readObject();
      
              String strReq = csr.getSubject().toString();
      
              strReq = strReq.substring(strReq.indexOf("CN=") + 3).trim();
              if (strReq.indexOf(",") > 0)
                  strReq = strReq.substring(0, strReq.indexOf(",")).trim();
              if (!strReq.equals(reqName)) {
                  return "";
              }
      
              AlgorithmIdentifier sigAlgId =
                  new DefaultSignatureAlgorithmIdentifierFinder().find("SHA1withRSA"); //SHA1withRSA
              AlgorithmIdentifier digAlgId =
                  new DefaultDigestAlgorithmIdentifierFinder().find(sigAlgId);
              X500Name issuer =
                  new X500Name(caCert.getSubjectX500Principal().getName());
              BigInteger serial = BigInteger.valueOf(SerNum);
      
              // The date object returns GMT format
              Date date = new Date(System.currentTimeMillis() - 180 * 1000);
              date.setHours(date.getHours() + addHours);
              Calendar cal = Calendar.getInstance();
              Date from = date;
              cal.setTime(date);
              cal.add(1, addYear);
              Date to = cal.getTime();
      
              SubjectPublicKeyInfo pkInfo = csr.getSubjectPublicKeyInfo();
              //SubjectPublicKeyInfo pkInfo = SubjectPublicKeyInfo.getInstance(kp.getPublic().getEncoded());
              RSAKeyParameters rsa =
                  (RSAKeyParameters)PublicKeyFactory.createKey(pkInfo);
              RSAPublicKeySpec rsaSpec =
                  new RSAPublicKeySpec(rsa.getModulus(), rsa.getExponent());
              KeyFactory kf = KeyFactory.getInstance("RSA");
              PublicKey rsaPub = kf.generatePublic(rsaSpec);
      
      
              X509v3CertificateBuilder certgen =
                  new X509v3CertificateBuilder(issuer, serial, from, to,
                                               csr.getSubject(),
                                               csr.getSubjectPublicKeyInfo());
      
              certgen.addExtension(X509Extension.basicConstraints, false,
                                   new BasicConstraints(false));
              certgen.addExtension(X509Extension.subjectKeyIdentifier, false,
                                   new SubjectKeyIdentifier(pkInfo));
              //            certgen.addExtension(X509Extension.subjectKeyIdentifier, false,
              //                                 new SubjectKeyIdentifierStructure(rsaPub)); // In old version done with much more extensive parsing
              certgen.addExtension(X509Extensions.AuthorityKeyIdentifier, false,
                                   new AuthorityKeyIdentifierStructure(caCert));
              //            certgen.addExtension(X509Extension.authorityKeyIdentifier, false,
              //                                 new AuthorityKeyIdentifier(new GeneralNames(new GeneralName(new X509Name(caCert.getSubjectX500Principal().getName()))),
              //                                                            caCert.getSerialNumber()));
      
              // add certificate purposes
              ASN1EncodableVector vector = new ASN1EncodableVector();
              vector.add(new DERObjectIdentifier("1.3.6.1.5.5.7.3.2"));
              vector.add(new DERObjectIdentifier("1.3.6.1.4.1.311.20.2.2"));
              vector.add(new DERObjectIdentifier("1.3.6.1.4.1.311.10.3.12"));
              vector.add(new DERObjectIdentifier("1.3.6.1.5.5.7.3.4"));
      
      
              DERSequence seq = new DERSequence(vector);
              certgen.addExtension(X509Extensions.ExtendedKeyUsage, false, seq);
      
      
              ContentSigner signer =
                  new BcRSAContentSignerBuilder(sigAlgId,
                                                digAlgId).build(PrivateKeyFactory.createKey(privateKey.getEncoded()));
              X509CertificateHolder holder = certgen.build(signer);
              byte[] certencoded = holder.toASN1Structure().getEncoded();
      
              CMSSignedDataGenerator generator = new CMSSignedDataGenerator();
              signer =
                  new JcaContentSignerBuilder("SHA1withRSA").build(privateKey);
              generator.addSignerInfoGenerator(new JcaSignerInfoGeneratorBuilder(new JcaDigestCalculatorProviderBuilder().build()).build(signer,
                                                                                                                                         caCert));
              generator.addCertificate(new X509CertificateHolder(certencoded));
              generator.addCertificate(new X509CertificateHolder(caCert.getEncoded()));
              CMSTypedData content = new CMSProcessableByteArray(certencoded);
              CMSSignedData signeddata = generator.generate(content, true);
      
              result = Base64Utils.base64Encode(signeddata.getEncoded());
      
          } catch (Exception e) {
              result = e.toString();
              getStackTrace(e);
          }
          return result;
      }
      

      在我使用充气城堡 1.4 的旧版本代码中,我们使用了 X509V3CertificateGenerator,并且在返回用于构建链的内容之前,如下所示:

                  X509Certificate newCert =
                  certGen.generateX509Certificate(privateKey, "BC");
              //=============================
              List chain = new ArrayList();
              chain.add(newCert);
              //-------------------------------------------------
              //  create the CertPath with old BouncyCastle
              CertificateFactory fact =
                  CertificateFactory.getInstance("X.509", "BC");
              CertPath path = fact.generateCertPath(chain);
              result = Base64Utils.base64Encode(path.getEncoded("PKCS7"));
      

      更新:OK 案例已解决。感谢this thread显然在使用时:

      cacert.getSubjectX500Principal().getName()

      我得到了发行人的反向名称,这打破了链条,而是使用:

      cert.getSubjectX500Principal().getEncoded() 为我解决了这个问题!因此,当您的 CA 未通过受信任机构的验证时,请确保您正确获取名称。

      【讨论】:

        【解决方案5】:

        最后,这对我有用:

        KeyPair serverKeyPair = keyPairLoader.getKeyPair(); //my own class
        CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509", "BC");
        X509Certificate serverCertificate = getServerCertificate(certificateFactory);
        
        org.spongycastle.asn1.x509.Certificate eeX509CertificateStructure = signCertificateSigningRequest(
          jcaPKCS10CertificationRequest, keyPair, serverCertificate);
        
        java.security.cert.X509Certificate signedCertificate = readCertificateFromASN1Certificate(
          eeX509CertificateStructure, certificateFactory);
        

        代码在哪里

          private org.spongycastle.asn1.x509.Certificate signCertificateSigningRequest(
            JcaPKCS10CertificationRequest jcaPKCS10CertificationRequest,
            KeyPair keyPair, X509Certificate serverCertificate)
              throws IOException, OperatorCreationException, NoSuchAlgorithmException, InvalidKeyException
          {
            // Signing CSR
            AlgorithmIdentifier sigAlgId = new DefaultSignatureAlgorithmIdentifierFinder()
              .find("SHA1withRSA");
        
            X509v3CertificateBuilder certificateBuilder = new JcaX509v3CertificateBuilder(
                serverCertificate, 
                new BigInteger("1"), //serial
                new Date(System.currentTimeMillis()),
                new Date(System.currentTimeMillis() + 30L * 365L * 24L * 60L * 60L * 1000L),
                jcaPKCS10CertificationRequest.getSubject(),
                jcaPKCS10CertificationRequest.getPublicKey()
            /*).addExtension(
                new ASN1ObjectIdentifier("2.5.29.35"),
                false,
                new AuthorityKeyIdentifier(keyPair.getPublic().getEncoded())*/
            ).addExtension(
                    new ASN1ObjectIdentifier("2.5.29.19"),
                    false,
                    new BasicConstraints(false) // true if it is allowed to sign other certs
            ).addExtension(
                    new ASN1ObjectIdentifier("2.5.29.15"),
                    true,
                    new X509KeyUsage(
                        X509KeyUsage.digitalSignature |
                            X509KeyUsage.nonRepudiation   |
                            X509KeyUsage.keyEncipherment  |
                            X509KeyUsage.dataEncipherment));
        
            AsymmetricKeyParameter asymmetricKeyParameter =
                  PrivateKeyFactory.createKey(keyPair.getPrivate().getEncoded());
            //ContentSigner sigGen = new BcRSAContentSignerBuilder(sigAlgId, digAlgId).build(asymmetricKeyParameter);
            ContentSigner sigGen = new JcaContentSignerBuilder("SHA1withRSA").build(keyPair.getPrivate());
        
        
            X509CertificateHolder x509CertificateHolder = certificateBuilder.build(sigGen);
            org.spongycastle.asn1.x509.Certificate eeX509CertificateStructure =
              x509CertificateHolder.toASN1Structure();
            return eeX509CertificateStructure;
          }
        
          private X509Certificate readCertificateFromASN1Certificate(
            org.spongycastle.asn1.x509.Certificate eeX509CertificateStructure,
            CertificateFactory certificateFactory)
            throws IOException, CertificateException {
            // Read Certificate
            InputStream is1 = new ByteArrayInputStream(eeX509CertificateStructure.getEncoded());
            X509Certificate signedCertificate =
              (X509Certificate) certificateFactory.generateCertificate(is1);
            return signedCertificate;
          }
        

        这可以转换为 PEM:

          private String convertCertificateToPEM(X509Certificate signedCertificate) throws IOException {
            StringWriter signedCertificatePEMDataStringWriter = new StringWriter();
            JcaPEMWriter pemWriter = new JcaPEMWriter(signedCertificatePEMDataStringWriter);
            pemWriter.writeObject(signedCertificate);
            pemWriter.close();
            log.info("PEM data:");
            log.info("" + signedCertificatePEMDataStringWriter.toString());
            return signedCertificatePEMDataStringWriter.toString();
          }
        

        【讨论】:

        • 如果我想设置自己的 CA,值是什么
        • new BasicConstraints(false) 应该是真的,尽管我认为我们使用 jamielinux 网站上关于“如何设置 CA 证书”的指南创建了 CA 证书
        • 我使用了这个代码,它确实生成了由 CA 签名的证书,但是我在客户端面临签名不匹配错误(使用这个证书),如果你可以检查并帮助我@ 987654323@
        【解决方案6】:

        这是我在 C# 中使用 BouncyCastle NuGet 包版本 1.8.9 的解决方案:

        public static X509Certificate2 SignCertificate(TextReader pemEncodedCsrReader, X509Certificate2 caCertificate, AsymmetricKeyParameter issuerPrivateKey)
        {
            var csr = (Pkcs10CertificationRequest)new PemReader(pemEncodedCsrReader).ReadObject();
        
            var certificateGenerator = new X509V3CertificateGenerator();
            certificateGenerator.SetNotBefore(DateTime.Now.Date);
            certificateGenerator.SetNotAfter(DateTime.Now.Date.AddYears(20));
            certificateGenerator.SetIssuerDN(new X509Name(caCertificate.IssuerName.Name));
            certificateGenerator.SetSubjectDN(csr.GetCertificationRequestInfo().Subject);
            certificateGenerator.SetPublicKey(PublicKeyFactory.CreateKey(csr.GetCertificationRequestInfo().SubjectPublicKeyInfo);
            var serialNumber = BigIntegers.CreateRandomInRange(BigInteger.One, BigInteger.ValueOf(long.MaxValue), random);
            certificateGenerator.SetSerialNumber(serialNumber);
        
            certificateGenerator.AddExtension(X509Extensions.BasicConstraints, false, new BasicConstraints(cA: false));
            certificateGenerator.AddExtension(X509Extensions.SubjectKeyIdentifier, false,
                new SubjectKeyIdentifier(csr.GetCertificationRequestInfo().SubjectPublicKeyInfo));
            certificateGenerator.AddExtension(X509Extensions.AuthorityKeyIdentifier, false,
                new AuthorityKeyIdentifier(new GeneralNames(new GeneralName(new X509Name(caCertificate.SubjectName.Name))), new BigInteger(caCertificate.SerialNumber, 16)));
        
            var signatureFactory = new Asn1SignatureFactory(SignatureAlgorithm, issuerPrivateKey, random);
            var certificate = certificateGenerator.Generate(signatureFactory);
            return new X509Certificate2(certificate.GetEncoded());
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2019-08-25
          • 2011-01-02
          • 1970-01-01
          • 1970-01-01
          • 2013-02-06
          • 2012-03-24
          • 2019-01-12
          相关资源
          最近更新 更多