如何从Java中的X509Certificate获取CRL

2020年11月20日 79点热度 0条评论

我有一个X509证书,派生自CMSSignedData(PKCS7)。我的问题是如何获取CRL文件的URL,以检查证书是否已被撤销。我试过下面的代码:

X509CertificateHolder signerCertificateHolder = (X509CertificateHolder) certIt.next();
X509Certificate certificate = new JcaX509CertificateConverter().setProvider("BC").getCertificate(signerCertificateHolder);
X509CRLEntry revokedCertificate;
X509CRL crl;

URL url = new URL("???");
URLConnection connection = url.openConnection();

try(DataInputStream inStream = new DataInputStream(connection.getInputStream()))
{
 crl = (X509CRL) cf.generateCRL(inStream);
}

revokedCertificate = crl.getRevokedCertificate(certificate.getSerialNumber());

if(revokedCertificate != null)
{
 System.out.println("Revoked");
}
else
{
 System.out.println("Valid");
}

它会很好地工作,除非我无法获得CRL的URL。我知道它具有OI(对象标识符)-2.5.29.31。但是很遗憾,我不能从证书中获取它。我怎样才能做到这一点?

解决方案如下:

找到此代码段here,它将打印证书中的所有CRL。

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.List;

import org.bouncycastle.asn1.ASN1InputStream;
import org.bouncycastle.asn1.ASN1Primitive;
import org.bouncycastle.asn1.DERIA5String;
import org.bouncycastle.asn1.DEROctetString;
import org.bouncycastle.asn1.x509.CRLDistPoint;
import org.bouncycastle.asn1.x509.DistributionPoint;
import org.bouncycastle.asn1.x509.DistributionPointName;
import org.bouncycastle.asn1.x509.Extension;
import org.bouncycastle.asn1.x509.GeneralName;
import org.bouncycastle.asn1.x509.GeneralNames;

public class CertCRL
{

    public static void main(String[] args)
    {
        try
        {
            CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");

            X509Certificate certificate = (X509Certificate) certificateFactory.generateCertificate(new FileInputStream(new File("CERT_FILE_PATH")));

            byte[] crlDistributionPointDerEncodedArray = certificate.getExtensionValue(Extension.cRLDistributionPoints.getId());

            ASN1InputStream oAsnInStream = new ASN1InputStream(new ByteArrayInputStream(crlDistributionPointDerEncodedArray));
            ASN1Primitive derObjCrlDP = oAsnInStream.readObject();
            DEROctetString dosCrlDP = (DEROctetString) derObjCrlDP;

            oAsnInStream.close();

            byte[] crldpExtOctets = dosCrlDP.getOctets();
            ASN1InputStream oAsnInStream2 = new ASN1InputStream(new ByteArrayInputStream(crldpExtOctets));
            ASN1Primitive derObj2 = oAsnInStream2.readObject();
            CRLDistPoint distPoint = CRLDistPoint.getInstance(derObj2);

            oAsnInStream2.close();

            List<String> crlUrls = new ArrayList<String>();
            for (DistributionPoint dp : distPoint.getDistributionPoints())
            {
                DistributionPointName dpn = dp.getDistributionPoint();
                // Look for URIs in fullName
                if (dpn != null)
                {
                    if (dpn.getType() == DistributionPointName.FULL_NAME)
                    {
                        GeneralName[] genNames = GeneralNames.getInstance(dpn.getName()).getNames();
                        // Look for an URI
                        for (int j = 0; j < genNames.length; j++)
                        {
                            if (genNames[j].getTagNo() == GeneralName.uniformResourceIdentifier)
                            {
                                String url = DERIA5String.getInstance(genNames[j].getName()).getString();
                                crlUrls.add(url);
                            }
                        }
                    }
                }
            }

            for (String url : crlUrls)
                System.out.println(url);
        }
        catch (Throwable e)
        {
            e.printStackTrace();
        }
    }

}