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

Is it possible to generate a signed certificate with an existing CA which has a different key pair?

我按照我在 post 中的说明使用现有 CA 创建了签名证书:

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

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

我尝试了下面的示例代码 post 但我的 pdf 签名无效:Generating X509 Certificate using Bouncy Castle Java

如果有任何意见或信息对我有帮助,我将不胜感激。

提前致谢。

public 密钥证书 (PKC) 将具有与颁发者相同的密钥对(public 密钥)仅当 证书是自有证书时签了一个CA 始终可以为另一个密钥对颁发证书,在这种情况下,新证书将具有新密钥对的 public 密钥,并由 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: public 密钥对应于将为其颁发新证书的新密钥对。

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

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

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

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