是否可以使用具有不同密钥对的现有CA生成签名证书?

时间:2018-08-19 20:36:48

标签: java bouncycastle signature ca csr

正如我在这篇帖子中所解释的,我使用现有的CA创建签名证书:Bouncy Castle: Signed Certificate with an existing CA

但是,我生成的证书具有与CA证书相同的公钥和私钥。

是否可以生成具有另一个密钥对的证书?

我已经尝试了以下文章中的示例代码,但我的pdf签名无效:Generating X509 Certificate using Bouncy Castle Java

我将感谢您提供的任何评论或信息。

谢谢。

1 个答案:

答案 0 :(得分:1)

仅当公钥证书(PKC)是自签名证书时,公钥证书(PKC)与颁发者具有相同的密钥对(公钥)。 CA总是有可能为另一个密钥对颁发证书,在这种情况下,新证书将具有新密钥对的公钥,并由CA的私钥签名。可以将新证书的主题设置为CA(通过BasicConstraint扩展和KeyUsage扩展),在这种情况下,可以使用新的密钥对来颁发其他证书,从而创建证书路径或链。请参见以下代码段。

public static X509Certificate getCertificte(X500Name subject,
                                          PublicKey subjectPublicKey,
                                          boolean isSubjectCA,
                                          X509Certificate caCertificate,
                                          PrivateKey caPrivateKey,
                                          String signingAlgorithm,
                                          Date validFrom,
                                          Date validTill) throws CertificateEncodingException {

BigInteger sn = new BigInteger(64, random);

X500Name issuerName = new X500Name(caCertificate.getSubjectDN().getName());
SubjectPublicKeyInfo subjectPublicKeyInfo = SubjectPublicKeyInfo.getInstance(subjectPublicKey.getEncoded());

X509v3CertificateBuilder certBuilder = new X509v3CertificateBuilder(issuerName,
                                                                    sn,
                                                                    validFrom,
                                                                    validTill,
                                                                    subject,
                                                                    subjectPublicKeyInfo);

JcaX509ExtensionUtils extensionUtil;
try {
  extensionUtil = new JcaX509ExtensionUtils();
} catch (NoSuchAlgorithmException e) {
  throw new RuntimeException("No provider found for SHA1 message-digest");
}

// Add extensions
try {
  AuthorityKeyIdentifier authorityKeyIdentifier = extensionUtil.createAuthorityKeyIdentifier(caCertificate);
  certBuilder.addExtension(Extension.authorityKeyIdentifier, false, authorityKeyIdentifier);

  SubjectKeyIdentifier subjectKeyIdentifier = extensionUtil.createSubjectKeyIdentifier(subjectPublicKey);
  certBuilder.addExtension(Extension.subjectKeyIdentifier, false, subjectKeyIdentifier);

  BasicConstraints basicConstraints = new BasicConstraints(isSubjectCA);
  certBuilder.addExtension(Extension.basicConstraints, true, basicConstraints);
} catch (CertIOException e) {
  throw new RuntimeException("Could not add one or more extension(s)");
}

ContentSigner contentSigner;
try {
  contentSigner = new JcaContentSignerBuilder(signingAlgorithm).build(caPrivateKey);
} catch (OperatorCreationException e) {
  throw new RuntimeException("Could not generate certificate signer", e);
}

try {
   return new JcaX509CertificateConverter().getCertificate(certBuilder.build(contentSigner));
 } catch (CertificateException e) {
   throw new RuntimeException("could not generate certificate", e);
 }
}

请注意以下参数:
subjectPublicKey :与将为其颁发新证书的新密钥对相对应的公钥。

caCertificate :与当前CA的密钥对相对应的CA证书。

caPrivateKey :CA的私钥(与上述caCertificate对应的私钥)。这将用于签署新证书。

isSubjectCA :一个布尔值,指示新证书持有者( subject )是否将充当CA。

为简洁起见,我省略了keyUsage扩展,该扩展应用于指示应使用所有与新证书相对应的公钥的所有目的。