使用DEROctetString与纯扩展(Using DEROctetString vs pure Extension)

2 IT屋

I am using bouncy castle librarires to add extensions to my X509V3Certificate certificate.Let's say that I want to add ExtendedKeyUsage extension to my certificate.I am using X509V3CertificateBuilder class and addExtension() method so I do this.

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

But what I am seeing in some examples all over the web , people are doing next thing

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

I don't get any warnings from compiler when I use first method(without DEROctetString) but I don't know what is the difference, which way is better, and are they both correct?

解决方案

TLDR: your (first) method is correct

For background, the actual extensions field in (the body=TBSCertificate of) an X.509 certificate represents/encodes the value of each extension as an OCTET STRING 'wrapping' the DER encoding of the actual value.

But in Bouncy when calling the older overloads of X509v3CertificateBuilder.addExtension whose third paramater is either ASN1Encodable (the value object) or byte[] (its encoding) you don't need to do the OCTET STRING yourself; the ExtensionsGenerator used internally by the builder does it for you. In fact, creating DEROctetString yourself here actually creates (a cert containing) an extension whose value is 'double wrapped' -- an OCTET STRING containing the DER of another OCTET STRING containing the DER of the actual value, which is wrong.

However, recent versions (1.53 up) contain another overload which instead of separate OID, boolean, value takes a single org.bouncycastle.asn1.x509.Extension object which contains those three -- and creating that object is different: its constructors take either the encoding (and wrap it) or a DEROctetString object you create yourself, and whose constructors in turn take either the encoding or the encodable. (It's actually declared as the superclass ASN1OctetString but you want to use the DER subclass because cert bodies need to be entirely DER.) Thus (any of) the following are also correct:

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())))

Are you sure it is not one of the latter two that you saw elsewhere?

我正在使用充气城堡librarires向我的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证书(正文中的 TBSCertificate )中的实际扩展名字段表示/编码该值每个扩展名作为OCTET STRING"包装"实际值的DER编码



但是在Bouncy中,调用较旧的 X509v3CertificateBuilder.addExtension 的重载时,其第三个参数为 ASN1Encodable (值对象)或 byte [] (其编码),您无需自己进行OCTET STRING;构建器内部使用的 ExtensionsGenerator 会为您完成此操作。实际上,在这里自己创建 DEROctetString 实际上会创建(包含证书的)扩展名,其值是"双重包装"的-一个OCTET STRING包含另一个OCTET STRING的DER,该扩展名包含



但是,最新版本(1.53以上)包含另一个重载,而不是单独的OID(布尔值),值只需要一个 org.bouncycastle.asn1.x509.Extension 对象,其中包含这三个对象-创建该对象是不同的:其构造函数采用编码(并包装)或<$ c您创建自己的$ c> DEROctetString 对象,该对象的构造函数又采用编码或可编码。 (它实际上被声明为超类 ASN1OctetString ,但您想使用 DER 子类,因为证书正文必须完全为DER 。)因此,以下任何一项也都是正确的:



  certbuilder.addExtension(new Extension(Extension.extendedKeyUsage,false, eku.getEncoded()))
certbuilder.addExtension(新扩展名(Extension.extendedKeyUsage,false,新DEROctetString(eku)))
certbuilder.addExtension(新扩展名(Extension.extendedKeyUsage,false,新DEROctetString (eku.getEncoded())))


您确定它不是后两者之一你在其他地方看到过?


本文地址:IT屋 » 使用DEROctetString与纯扩展