我找不到任何描述如何使用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)
我很难弄清楚从证书生成器获取的内容以PEM或DER格式存储。
还是我一起走错了路?
好的…我一直在寻找做同样的事情,对于我的一生,我不知道该怎么做。所有的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的杀手section- http://en.wikipedia.org/wiki/PKCS