如何在java的X509Certificate中获取基本约束的策略标识符和主题类型
我有一个java版本的X509Certificate,我想获取如何在java的X509Certificate中获取基本约束的策略标识符和主题类型,java,cryptography,certificate,x509certificate,x509certificate2,Java,Cryptography,Certificate,X509certificate,X509certificate2,我有一个java版本的X509Certificate,我想获取策略标识符的值,该值存在于证书策略字段中,如下图所示: 此外,我还想获得
策略标识符的值,该值存在于证书策略
字段中,如下图所示:
此外,我还想获得
字段中主题类型的值,如下图所示:
我的代码:
public static void main(String[] args) throws Exception {
CertificateFactory cf = CertificateFactory.getInstance("X509");
InputStream in = new FileInputStream(new File("E:\\myCert.crt"));
X509Certificate cert = (X509Certificate) cf.generateCertificate(in);
int length = cert.getCertificateExtensionOIDs().size();
String oid;
for(int i = 0; i < length; i++){
oid = cert.getCertificateExtensionOIDs().iterator().next();
byte[] UID = cert.getExtensionValue(oid);
DERObject derObject = toDERObject(UID);
if(derObject instanceof DEROctetString){
DEROctetString derOctetString = (DEROctetString) derObject;
derObject = toDERObject(derOctetString.getOctets());
}
// here I think, I should use derObject to retrieve cert info but I don't know how!?
}
public static DERObject toDERObject(byte[] data) throws IOException {
ByteArrayInputStream inStream = new ByteArrayInputStream(data);
ASN1InputStream DIS = new ASN1InputStream(inStream);
return DIS.readObject();
}
publicstaticvoidmain(字符串[]args)引发异常{
CertificateFactory cf=CertificateFactory.getInstance(“X509”);
InputStream in=新文件InputStream(新文件(“E:\\myCert.crt”);
X509证书证书=(X509证书)cf.generateCertificate(in);
int length=cert.getCertificateExtensionOIDs().size();
字符串oid;
for(int i=0;i
查看该代码。可能需要多一点数据验证代码,您必须仔细检查基本约束,因为在某些情况下,以下条件可能不够
import org.bouncycastle.asn1.ASN1InputStream;
import org.bouncycastle.asn1.ASN1Sequence;
import org.bouncycastle.asn1.DEROctetString;
import org.bouncycastle.asn1.x509.CertificatePolicies;
import org.bouncycastle.asn1.x509.PolicyInformation;
import java.io.ByteArrayInputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.security.InvalidKeyException;
import java.security.SignatureException;
import java.security.cert.Certificate;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
/**
* 2016 krzysiek
*/
public class App {
private static final String CERTIFICATE_POLICY_OID = "2.5.29.32";
private static final String FILENAME = "/test.cer";
public static void main(String[] args) {
try {
X509Certificate cert = loadCertificate();
String policyIdentifier = getCertificatePolicyId(cert, 0, 0);
System.out.println("Policy Identifier: " + policyIdentifier);
String subjectType = getSubjectType(cert);
System.out.println("Subject Type: " + subjectType);
} catch (Exception e) {
System.out.println("Problem with certificate: " + e.getMessage());
}
}
private static String getSubjectType(X509Certificate cert) {
int pathLen = cert.getBasicConstraints();
if (pathLen == -1) {
if (cert.getKeyUsage()[5] || cert.getKeyUsage()[6]) { //simple check, there my be needed more key usage and extended key usage verification
return "Service";
} else {
return "EndEntity";
}
} else {
try {
cert.verify(cert.getPublicKey());
return "RootCA";
} catch (SignatureException | InvalidKeyException e) {
return "SubCA";
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
private static X509Certificate loadCertificate() {
try (InputStream in = new FileInputStream(App.class.getResource(FILENAME).getFile())) {
CertificateFactory cf = CertificateFactory.getInstance("X.509");
Certificate certificate = cf.generateCertificate(in);
X509Certificate cert = (X509Certificate) certificate;
return cert;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public static String getCertificatePolicyId(X509Certificate cert, int certificatePolicyPos, int policyIdentifierPos)
throws IOException {
byte[] extPolicyBytes = cert.getExtensionValue(CERTIFICATE_POLICY_OID);
if (extPolicyBytes == null) {
return null;
}
DEROctetString oct = (DEROctetString) (new ASN1InputStream(new ByteArrayInputStream(extPolicyBytes)).readObject());
ASN1Sequence seq = (ASN1Sequence) new ASN1InputStream(new ByteArrayInputStream(oct.getOctets())).readObject();
if (seq.size() <= (certificatePolicyPos)) {
return null;
}
CertificatePolicies certificatePolicies = new CertificatePolicies(PolicyInformation.getInstance(seq.getObjectAt(certificatePolicyPos)));
if (certificatePolicies.getPolicyInformation().length <= policyIdentifierPos) {
return null;
}
PolicyInformation[] policyInformation = certificatePolicies.getPolicyInformation();
return policyInformation[policyIdentifierPos].getPolicyIdentifier().getId();
}
}
import org.bounchycastle.asn1.ASN1InputStream;
导入org.bouncycastle.asn1.asn1序列;
导入org.bouncycastle.asn1.DEROctetString;
导入org.bouncycastle.asn1.x509.CertificatePolicys;
导入org.bouncycastle.asn1.x509.PolicyInformation;
导入java.io.ByteArrayInputStream;
导入java.io.FileInputStream;
导入java.io.IOException;
导入java.io.InputStream;
导入java.security.InvalidKeyException;
导入java.security.SignatureException;
导入java.security.cert.Certificate;
导入java.security.cert.CertificateFactory;
导入java.security.cert.x509证书;
/**
*2016年krzysiek
*/
公共类应用程序{
私有静态最终字符串证书\u策略\u OID=“2.5.29.32”;
私有静态最终字符串FILENAME=“/test.cer”;
公共静态void main(字符串[]args){
试一试{
X509Certificate cert=loadCertificate();
字符串policyIdentifier=getCertificatePolicyId(证书,0,0);
System.out.println(“策略标识符:“+policyIdentifier”);
字符串subjectType=getSubjectType(证书);
System.out.println(“主题类型:“+subjectType”);
}捕获(例外e){
System.out.println(“证书问题:+e.getMessage());
}
}
私有静态字符串getSubjectType(X509证书证书证书){
int pathLen=cert.getBasicConstraints();
如果(路径==-1){
如果(cert.getKeyUsage()[5]| | cert.getKeyUsage()[6]){//简单检查,则需要更多密钥使用和扩展密钥使用验证
返回“服务”;
}否则{
回归“亲昵”;
}
}否则{
试一试{
cert.verify(cert.getPublicKey());
返回“RootCA”;
}捕获(SignatureException | InvalidKeyException e){
返回“SubCA”;
}捕获(例外e){
抛出新的运行时异常(e);
}
}
}
私有静态X509Certificate loadCertificate(){
try(InputStream in=newfileinputstream(App.class.getResource(FILENAME.getFile())){
CertificateFactory cf=CertificateFactory.getInstance(“X.509”);
证书=cf.generateCertificate(in);
X509证书证书=(X509证书)证书;
返回证书;
}捕获(例外e){
抛出新的运行时异常(e);
}
}
公共静态字符串getCertificatePolicyId(X509Certificate证书、int certificatePolicyPos、int policyIdentifierPos)
抛出IOException{
字节[]extPolicyBytes=cert.getExtensionValue(证书\u策略\u OID);
if(extPolicyBytes==null){
返回null;
}
DEROctetString oct=(DEROctetString)(新的ASN1InputStream(新的ByteArrayInputStream(extPolicyBytes)).readObject());
ASN1Sequence seq=(ASN1Sequence)新的ASN1InputStream(新的ByteArrayInputStream(oct.getOctets()).readObject();
如果(seq.size()谢谢@Krzysiek,`CertificatePolicys CertificatePolicys=new CertificatePolicys(PolicyInformation.getInstance(seq.getObjectAt(certificatePolicyPos));`行出现以下错误:无法解析构造函数CertificatePolicys
,另外,下一行:CertificatePolicy.getPolicyInformation()
出现以下错误:无法解析方法getPolicyInformation()@H.Aqjn您使用的是哪个版本的BouncyCastle?我已经用1.54编译了代码:我使用的是org.BouncyCastle:bcprov-jdk16:1.46
您的解决方案完全解决了我的问题,只是它与我从crlDistributionPoints获取crls的部分代码有冲突。我正在使用此代码:为什么您的解决方案与t不兼容bouncyCastle的最后一个版本?我认为您的方法中的一些方法可能会被弃用。您能否提供一个好的代码(BC的最后一个版本)来获取getCrlDistributionPoints列表并一起解决这个问题?
<properties>
<bouncycastle.version>1.54</bouncycastle.version>
</properties>
<dependencies>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
<version>${bouncycastle.version}</version>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcmail-jdk15on</artifactId>
<version>${bouncycastle.version}</version>
</dependency>
</dependencies>