我有一个 X509Certificate
,我想编程确定其类型(扩展验证(EV SSL),组织验证(OV SSL)或已验证的域(DV SSL))。
我使用Bouncycastle Cryptoapi读了我的证书。例如,这是我从文件中阅读并获取发行人和主题通用名称(CN)的方式:
...
CertificateFactory cf = CertificateFactory.getInstance("X.509");
FileInputStream input = new FileInputStream(certfile);
X509Certificate cert = (X509Certificate)cf.generateCertificate(input);
X500Name x500name = new JcaX509CertificateHolder(cert).getSubject();
X500Name issuer = new JcaX509CertificateHolder(cert).getIssuer();
...
如何在程序中获得给定证书的类型?
我正在使用 Bouncycastle 1.57 。如果您使用版本<1.47,代码可能有所不同,因为在1.47中,它们对API做出了重大更改(尽管想法是相同的)。
要检查证书是DV还是OV,您可以检查证书策略扩展名,如本答案和GlobalSign网站中所述:
Type Policy Identifier
Domain Validated 2.23.140.1.2.1
Organization Validated 2.23.140.1.2.2
拥有这些标识符给我们带来了我们对确定证书发行政策评估的目标的很长一段路 - 也就是说,并非所有CAS都已经采用了它们。
请注意,此方法不能100%保证,因为所有证书机构均未完全采用。也就是说,您可以使用以下方式使用Bouncycastle检查此扩展:
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
import org.bouncycastle.asn1.DLSequence;
import org.bouncycastle.x509.extension.X509ExtensionUtil;
X509Certificate cert = // get certificate
byte[] value = cert.getExtensionValue("2.5.29.32");
if (value != null) { // extension is present
// CertificatePolicies is a sequence
DLSequence seq = (DLSequence) X509ExtensionUtil.fromExtensionValue(value);
for (int i = 0; i < seq.size(); i++) {
// each element is also a sequence
DLSequence s = (DLSequence) seq.getObjectAt(i);
// first element is an OID
String oid = ((ASN1ObjectIdentifier) s.getObjectAt(0)).getId();
if ("2.23.140.1.2.1".equals(oid)) {
// DV
} else if ("2.23.140.1.2.2".equals(oid)) {
// OV
}
}
}
在技术视图中,证书类型没有什么不同。这更多是组织协议。
您可以检查主题的证书(您称为x500name
的变量)。如果此字段包含键jurisdictionOfIncorporationCountryName
和businessCategory
的值,则您有EV证书。然后,键serialNumber
指向该业务实体的一些合法注册密钥(例如我们的德语 handelsregisternummer ),密钥CN是该业务实体的注册名称。
据我所知,DV和OV之间的区别更多是一个营销功能。