使用 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())))
你确定这不是你在别处看到的后两者之一吗?
我正在使用充气城堡库为我的 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())))
你确定这不是你在别处看到的后两者之一吗?