如何在java的X509Certificate中获取基本约束的策略标识符和主题类型

如何在java的X509Certificate中获取基本约束的策略标识符和主题类型,java,cryptography,certificate,x509certificate,x509certificate2,Java,Cryptography,Certificate,X509certificate,X509certificate2,我有一个java版本的X509Certificate,我想获取策略标识符的值,该值存在于证书策略字段中,如下图所示: 此外,我还想获得

我有一个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>