在Java中导入DER/PEM时设置/获取X509 CertificatePolicys扩展
我在获取和设置Java中的证书策略扩展时遇到问题。我用的是弹跳城堡1.57 我正在向证书生成器添加扩展,如下所示:在Java中导入DER/PEM时设置/获取X509 CertificatePolicys扩展,java,bouncycastle,x509,Java,Bouncycastle,X509,我在获取和设置Java中的证书策略扩展时遇到问题。我用的是弹跳城堡1.57 我正在向证书生成器添加扩展,如下所示: boolean isCritical = Extensions.certificatePolicies; String cpValue = Extensions.certificatePoliciesValue; cerGen.addExtension(Extension.certificatePolicies, isCritical, cpValue.getBytes());
boolean isCritical = Extensions.certificatePolicies;
String cpValue = Extensions.certificatePoliciesValue;
cerGen.addExtension(Extension.certificatePolicies, isCritical, cpValue.getBytes());
得到这样的扩展:
byte[] policyBytes = certificate.getExtensionValue(Extension.certificatePolicies.toString());
if (policyBytes != null) {
Object policyObj = new ASN1InputStream(policyBytes).readObject();
policyBytes = ((DEROctetString) policyObj).getOctets();
String policyField = new String(policyBytes); // this is cpValue when set
}
在我导出证书之前,这项工作正常,但当我将其导出到DER或PEM类型时,当我尝试导入它时,会出现错误:
java.io.IOException:CertificatePolicyExtension的编码无效
以下是我的导入源代码:
CertificateFactory fact = CertificateFactory.getInstance("X.509");
FileInputStream is = new FileInputStream(file.getAbsolutePath());
X509Certificate cer = (X509Certificate) fact.generateCertificate(is);
当我尝试生成证书时,最后一行出现异常。发生错误的原因是您将扩展创建为单个
字符串
获取扩展的代码之所以有效,是因为您也将其作为单个字符串进行读取(您的读取方式与创建扩展的方式完全相同,这就是它的工作原理)
但是,证书策略扩展有一个良好的预定义格式,CertificateFactory
尝试根据此格式解析证书
在中,您可以找到扩展的格式:
certificatePolicies ::= SEQUENCE SIZE (1..MAX) OF PolicyInformation
PolicyInformation ::= SEQUENCE {
policyIdentifier CertPolicyId,
policyQualifiers SEQUENCE SIZE (1..MAX) OF
PolicyQualifierInfo OPTIONAL }
CertPolicyId ::= OBJECT IDENTIFIER
PolicyQualifierInfo ::= SEQUENCE {
policyQualifierId PolicyQualifierId,
qualifier ANY DEFINED BY policyQualifierId }
-- policyQualifierIds for Internet policy qualifiers
id-qt OBJECT IDENTIFIER ::= { id-pkix 2 }
id-qt-cps OBJECT IDENTIFIER ::= { id-qt 1 }
id-qt-unotice OBJECT IDENTIFIER ::= { id-qt 2 }
PolicyQualifierId ::= OBJECT IDENTIFIER ( id-qt-cps | id-qt-unotice )
... and lots of other types definitions
请注意,扩展名不是字符串
。这是一个策略信息序列
,它是一个标识符和限定符序列,等等
我创建了一个只有一个值的示例扩展,作为示例:
import org.bouncycastle.asn1.x509.CertificatePolicies;
import org.bouncycastle.asn1.x509.Extension;
import org.bouncycastle.asn1.x509.PolicyInformation;
import org.bouncycastle.asn1.x509.PolicyQualifierId;
import org.bouncycastle.asn1.x509.PolicyQualifierInfo;
import org.bouncycastle.cert.X509v3CertificateBuilder;
X509v3CertificateBuilder certGen = //create builder
boolean isCritical = true; // depends on your application (setting any value for tests)
PolicyQualifierInfo pqInfo = new PolicyQualifierInfo("aaa.bbb"); // the value you want
PolicyInformation policyInfo = new PolicyInformation(PolicyQualifierId.id_qt_cps, new DERSequence(pqInfo));
CertificatePolicies policies = new CertificatePolicies(policyInfo);
certGen.addExtension(Extension.certificatePolicies, isCritical, policies);
要阅读此扩展,您可以执行以下操作:
import org.bouncycastle.x509.extension.X509ExtensionUtil;
X509Certificate certificate = // a java.security.cert.X509Certificate
byte[] policyBytes = certificate.getExtensionValue(Extension.certificatePolicies.toString());
if (policyBytes != null) {
CertificatePolicies policies = CertificatePolicies.getInstance(X509ExtensionUtil.fromExtensionValue(policyBytes));
PolicyInformation[] policyInformation = policies.getPolicyInformation();
for (PolicyInformation pInfo : policyInformation) {
ASN1Sequence policyQualifiers = (ASN1Sequence) pInfo.getPolicyQualifiers().getObjectAt(0);
System.out.println(policyQualifiers.getObjectAt(1)); // aaa.bbb
}
}
通过这种方式创建证书,fact.generateCertificate
将创建无错误的证书。您的cpValue
变量中有什么?@Hugo它是CPS URI字段,即cpValue=“aaa.bbb”。好的,我将进行一些测试。你的BouncyCastle版本是什么?@Hugo我使用的是bcprov-jdk15on-157.jar和bcpkix-jdk15on-1.57.jar。反应很好!非常感谢你!我成功了。请注意,现在应该使用JcaX509ExtensionUtils.parseExtensionValue(policyBytes)
而不是X509ExtensionUtil.fromExtensionValue(policyBytes)
。