正如我在这篇帖子中所解释的,我使用现有的CA创建签名证书:Bouncy Castle: Signed Certificate with an existing CA
但是,我生成的证书具有与CA证书相同的公钥和私钥。
是否可以生成具有另一个密钥对的证书?
我已经尝试了以下文章中的示例代码,但我的pdf签名无效:Generating X509 Certificate using Bouncy Castle Java
我将感谢您提供的任何评论或信息。
谢谢。
答案 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扩展,该扩展应用于指示应使用所有与新证书相对应的公钥的所有目的。