openssl使用Bouncy Castle在Java中创建自定义X509 v3扩展
我已经成功地使用Bouncy Castle的X509v3CertificateBuilder Java类创建了带有标准V3扩展的X509证书。我现在正在尝试创建带有自定义扩展名的证书
我可以使用addExtension(…)创建自定义扩展方法,但是,证书中的结果值不是我想要的。例如,我希望在自定义OID 1.2.3.4“00 00 00 FF FF FF”下的证书中列出这些精确的八位字节。我尝试过的每件事都用ASN1编码将八位字节字符串包装起来,结果是“04 08 00 00 00 FF FF FF”
基本上,我想用Java创建一个具有自定义扩展名的证书,该扩展名与使用具有以下配置的扩展名文件使用OpenSSL创建证书时的外观相同:
1.2.3.4=DER:00:00:00:00:FF:FF:FF:FF
X509v3CertificateBuilder类是否可以以干净的方式实现这一点
下面是创建“不正确”值的代码片段
// Raw value to place in cert for OID 1.2.3.4.
byte[] bytearray = {0, 0, 0, 0, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF};
ASN1ObjectIdentifier asn1oid = new ASN1ObjectIdentifier("1.2.3.4");
Extension ext = new Extension(asn1oid, false, bytearray);
X509v3CertificateBuilder certBldr =
new JcaX509v3CertificateBuilder(
caCert,
serial,
startDate,
endDate,
dn,
pubKey)
.addExtension(
new ASN1ObjectIdentifier("2.5.29.19"),
false,
new BasicConstraints(false))
.addExtension(
new ASN1ObjectIdentifier("2.5.29.15"),
true,
new X509KeyUsage(
X509KeyUsage.digitalSignature |
X509KeyUsage.nonRepudiation |
X509KeyUsage.keyEncipherment |
X509KeyUsage.dataEncipherment))
.addExtension(
new ASN1ObjectIdentifier("1.2.3.4"),
false,
ext.getExtnValue());
// Create and sign the certificate.
X509CertificateHolder certHolder = certBldr.build(sigGen);
X509Certificate cert = new JcaX509CertificateConverter().setProvider(BC)
.getCertificate(certHolder);
# 1 楼答案
证书是ASN。1编码,因此扩展值也应为ASN。1编码。04为八位字节字符串类型,08为该八位字节字符串的长度。BouncyCastle对扩展数据的格式一无所知,很可能这就是它不剥离标记和长度的原因,您应该手动解码该数据
# 2 楼答案
在尝试了许多不同的选项之后,我认为不可能使用X509v3CertificateBuilder创建具有原始(非ASN.1编码)值的扩展。addExtension()方法期望或更改输入值为ASN。1编码
然而,在查看了X509v3CertificateBuilder在幕后使用的方法的BouncyCastle源代码之后,我找到了一种使用其他类的方法。涉及的代码行更多,但它相当简单,并给出了所需的结果
下面是允许使用原始值进行自定义扩展的代码