Java 使用DEROctetString与纯扩展

Java 使用DEROctetString与纯扩展,java,certificate,bouncycastle,x509certificate,Java,Certificate,Bouncycastle,X509certificate,我正在使用bouncy castle Libraries向我的X509V3Certificate证书添加扩展。假设我想向我的证书添加ExtendedKeyUsage扩展。我正在使用X509V3CertificateBuilder类和addExtension()方法,所以我这样做了 X509V3CertificateBuilder cf=...; ExtendedKeyUsage eku = new ExtendedKeyUsage(KeyPurposeId.anyExtendedKe

我正在使用bouncy castle Libraries向我的X509V3Certificate证书添加扩展。假设我想向我的证书添加ExtendedKeyUsage扩展。我正在使用X509V3CertificateBuilder类和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证书的(body=
TBSCertificate
中的实际
extensions
字段表示/编码每个扩展的值

但是在Bouncy中,当调用
X509v3CertificateBuilder.addExtension的较旧重载时,其第三个参数是
ASN1Encodable
(值对象)或
byte[]
(其编码),您不需要自己编写八位字符串;构建器内部使用的
ExtensionsGenerator
为您完成此任务。事实上,在这里自己创建
DEROctetString
实际上创建了(一个包含)一个扩展名,其值是“双重包装的”——一个八位字符串包含另一个八位字符串的DER,该八位字符串包含实际值的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())))

您确定它不是您在其他地方看到的后两个吗?

使用ASN.1解析器并打印出差异?