如何从其文件中获取证书类型?
How to get a certificate type from its file?
我有一个 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();
...
如何在我的程序中获取给定证书的类型?
从技术角度来看,证书类型没有区别。它更像是一种组织协议。
您可以检查证书主题(您调用的变量 x500name
)。如果此字段包含密钥 jurisdictionOfIncorporationCountryName
和 businessCategory
的值,则您拥有 EV 证书。然后密钥 serialNumber
指向该商业实体的一些合法注册密钥(例如我们的德语 Handelsregisternummer),密钥 CN 是该商业实体的注册名称。
据我所知,DV 和 OV 之间的区别更多的是一种营销特征。
我正在使用 BouncyCastle 1.57。如果您使用的版本 < 1.47,代码可能会有所不同,因为在 1.47 中他们制作了 significant changes in the API(尽管想法相同)。
要检查证书是 DV 还是 OV,您可以检查 Certificate Policies extension, as explained in this answer and in GlobalSign's website:
Type Policy Identifier
Domain Validated 2.23.140.1.2.1
Organization Validated 2.23.140.1.2.2
Having these identifiers takes us a long way towards our goal of deterministic evaluation of certificate issuance policy — that said, not all CAs have yet adopted them.
请注意,此方法并非 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
}
}
}
我有一个 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();
...
如何在我的程序中获取给定证书的类型?
从技术角度来看,证书类型没有区别。它更像是一种组织协议。
您可以检查证书主题(您调用的变量 x500name
)。如果此字段包含密钥 jurisdictionOfIncorporationCountryName
和 businessCategory
的值,则您拥有 EV 证书。然后密钥 serialNumber
指向该商业实体的一些合法注册密钥(例如我们的德语 Handelsregisternummer),密钥 CN 是该商业实体的注册名称。
据我所知,DV 和 OV 之间的区别更多的是一种营销特征。
我正在使用 BouncyCastle 1.57。如果您使用的版本 < 1.47,代码可能会有所不同,因为在 1.47 中他们制作了 significant changes in the API(尽管想法相同)。
要检查证书是 DV 还是 OV,您可以检查 Certificate Policies extension, as explained in this answer and in GlobalSign's website:
Type Policy Identifier
Domain Validated 2.23.140.1.2.1
Organization Validated 2.23.140.1.2.2
Having these identifiers takes us a long way towards our goal of deterministic evaluation of certificate issuance policy — that said, not all CAs have yet adopted them.
请注意,此方法并非 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
}
}
}