0

的x509证书我有一个x509证书在java中的主体类型和我想要得到的Policy Identifier其中有在Certificate Policies领域存在的价值,如何获得的策略标识符和基本约束的在Java

enter image description here

另外,我想在Basic ConstraintsSubject Type的值,如所描绘的:在下面的图片描述如下图:

enter image description here

我的代码:

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

回答

1

看代码。我需要更多的数据验证代码,并且必须小心检查基本约束条件,因为在某些情况下,条件可能不够。

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> 
+0

谢谢@Krzysiek,但'CertificatePolicies certificatePolicies =新CertificatePolicies(PolicyInformation.getInstance(seq.getObjectAt(certificatePolicyPos)))行; '有这个错误:'无法解析构造函数CertiicatePolicies',另外,下一行:'certificatePolicies.getPolicyInformation()'有这个错误:无法解析方法getPolicyInformation() –

+0

@ H.Aqjn您使用的BouncyCastle的版本是?我已经编译了1.54的代码: – Krzysiek

+0

我正在使用'org.bouncycastle:bcprov-jdk16:1.46' –