How to get the Policy Identifier and the Subject Type of Basic Constraints in a X509Certificate of java

孤街浪徒 提交于 2019-12-02 04:46:33
Krzysiek

Look at that code. A little more data validation code may be needed and you have to be careful checking basic constraints, because the condition below may not be enough in some cases.

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();
    }
}

pom.xml:

<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>
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!