使用 DEROctetString 与纯扩展

Using DEROctetString vs pure Extension

我正在使用充气城堡库为我的 X509V3Certificate 添加扩展 certificate.Let 说我想为我的 certificate.I 添加 ExtendedKeyUsage 扩展使用 X509V3CertificateBuilder class 和 addExtension() 方法,所以我这样做了。

   X509V3CertificateBuilder cf=...;
   ExtendedKeyUsage eku = new ExtendedKeyUsage(KeyPurposeId.anyExtendedKeyUsage);
cf.addExtension(Extension.ExtendedKeyUsage, false , eku);

但我在网络上的一些例子中看到的是,人们正在做下一步

cf.addExtension(Extension.ExtendedKeyUsage, false, new DEROctetString(eku));

当我使用第一种方法(没有 DEROctetString)时,我没有从编译器收到任何警告,但我不知道有什么区别,哪种方法更好,它们都正确吗?

TLDR:你的(第一个)方法是正确的

作为背景,X.509 证书(正文=TBSCertificate)中的实际 extensions 字段 represents/encodes 每个扩展名的值 as an OCTET STRING 'wrapping' the DER encoding of the actual value

但是在 Bouncy 中,当调用第三个参数是 ASN1Encodable(值对象)或 byte[](其编码)的 X509v3CertificateBuilder.addExtension 的旧重载时,您不需要自己做 OCTET STRING;构建器内部使用的 ExtensionsGenerator 会为您完成。实际上,在这里自己创建 DEROctetString 实际上会创建(包含证书)一个值为 'double wrapped' 的扩展——一个 OCTET STRING 包含另一个包含实际值 DER 的 OCTET STRING 的 DER,即错了。

然而,最近的版本(1.53 以上)包含另一个重载,而不是单独的 OID、布尔值,值采用单个 org.bouncycastle.asn1.x509.Extension 对象,该对象包含这三个——并且创建该对象是不同的:它的构造函数采用编码(并包装它)或您自己创建的 DEROctetString 对象,其构造函数依次采用编码或可编码。 (它实际上被声明为超类 ASN1OctetString 但您想使用 DER 子类,因为证书主体需要完全是 DER。)因此(任何)以下也是正确的:

certbuilder.addExtension(new Extension(Extension.extendedKeyUsage, false, eku.getEncoded()))
certbuilder.addExtension(new Extension(Extension.extendedKeyUsage, false, new DEROctetString(eku)))
certbuilder.addExtension(new Extension(Extension.extendedKeyUsage, false, new DEROctetString(eku.getEncoded())))

你确定这不是你在别处看到的后两者之一吗?