How do I check if an X509 certificate has been revoked in Java?

前端 未结 2 410
离开以前
离开以前 2020-12-29 14:21

I have googled around all over the place for this, and asked in other communities, and I keep getting forwarded to the oracle document that discusses the spec. However, that

相关标签:
2条回答
  • 2020-12-29 14:56

    Every CA publishes the list of the certificates it has revoked. This list includes the serial number of the certificates and the revocation date

    to get the url of the certificate revocation list (CRL) follow the below steps

    • open the certificate
    • go to Details Tab and find the field "CRL Distribution Point" in the details list

    It will show you the value something like this

    [1]CRL Distribution Point Distribution Point Name: Full Name: URL=mscrl.microsoft.com/pki/mscorp/crl/msitwww2.crl URL=crl.microsoft.com/pki/mscorp/crl/msitwww2.crl

    So in your code you need to download these files and check for the certificate serial number in them to see if it's revoked or not

    Find below the sample code for it

    public class CertVerification {
    
    
        public static void main(String[] args) throws Exception {
    
            String certificatePath = "C:\\Users\\user1\\Desktop\\test.cer";
    
            CertificateFactory cf = CertificateFactory.getInstance("X509");
    
            X509Certificate certificate = null;
            X509CRLEntry revokedCertificate = null;
            X509CRL crl = null;
    
            certificate = (X509Certificate) cf.generateCertificate(new FileInputStream(new File(certificatePath)));
    
            URL url = new URL("http://<someUrl from certificate>.crl");
            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");
            }
    
        }
    
    
    }
    

    Please See

    These lists are updated periodically

    You can get these Revocation URL's from the certificate as well, i have just given an example

    This is just a basic example to give you a head start

    Update

    I found this sample class to check certificate, it also verifies with the CRL issued by the certificate's CA and certification chain, so you don't need to provide the CRL url as well

    https://svn.cesecore.eu/svn/ejbca/branches/Branch_3_2_3_utf8/ejbca/doc/samples/ValidateCertUseCRL.java

    0 讨论(0)
  • 2020-12-29 15:09

    A Certification Authority publish the status of the certificates using Online Certificate Service Protocol (OCSP) and Certificate Revocation Lists (CRL).

    Check the revocation of a certificate involves several steps:

    1. Extract the CRL distribution point and OCSP url from AIA extension included in the X509Certificate

    2. Download the CRL and check if the serial number of your certificate is included. Verify the signing certificate of the CRL and ensure is trusted (root CA in your truststore)

    3. Query online the OCSP service sending the serial number and the issuer to get the status. Check the signature of the OCSP response and ensure signing certificate is trusted (root CA in your truststore).

    4. Certificate is revoked if it is present in CRL or OCSP status is revoked. OCSP is recommended over CRLs, but it usual to query both service because could be down.

    As you can see the process is not simple at all. Check if a certificate is valid may consists in several invocations to OCSP service, downloading the certificate chain, verify signature of signing certificate of the CRLs and OCSP responses, and finally verify that the CA is trusted

    So I recommend not to use Java native methods directly if you are not going to take into account all these factors

    You can use BouncyCastle to manage CRL and query OCSP, but a better decision would be to use the SD-DSS framework (it uses also BouncyCastle), that pretty encapsulates all this stuff.

    Github SD-DSS: https://github.com/esig/dss Documentation: http://dss.nowina.lu/doc/dss-documentation.html


    Example

    Full example to validate a certificate checking revocation. Omit the steps of loading the trusted source and intermediates if you only want to check revocation

    //Load the certification chain, including the intemediate certificates and the trusted root.    
    CertificateToken issuerCert = DSSUtils.loadCertificate("/trusted.crt");
    CommonTrustedCertificateSource trustedCertificateSource = new CommonTrustedCertificateSource();
    trustedCertificateSource.addCertificate(issuerCert);
    
    CommonCertificateSource adjunctCertificateSource = new CommonCertificateSource();
    CertificateToken intermediateCert = DSSUtils.loadCertificate("/intermediate.cer");
    adjunctCertificateSource.addCertificate(intermediateCert);
    
    //Load the certificate to verify
    CertificateToken toValidateX509Certificate = DSSUtils.loadCertificate("/toValidate.crt");
    CertificateToken toValidateCertificateToken = adjunctCertificateSource.addCertificate(toValidateX509Certificate);
    
    //Configure the certificate verifier using the trust store and the intermediate certificates
    //OnlineOCSPSource and OnlineCRLSource will invoke the OCSP service and CRL
    //distribution point extracting the URL  from the certificate
    CertificateVerifier certificateVerifier = new CommonCertificateVerifier();
    certificateVerifier.setTrustedCertSource(trustedCertificateSource);
    certificateVerifier.setAdjunctCertSource(adjunctCertificateSource);     
    certificateVerifier.setCrlSource(new OnlineCRLSource());
    certificateVerifier.setOcspSource(new OnlineOCSPSource());
    
    //Perform validation 
    CertificatePool validationPool = certificateVerifier.createValidationPool();
    SignatureValidationContext validationContext = new SignatureValidationContext(validationPool);
    validationContext.addCertificateTokenForVerification(toValidateCertificateToken);
    validationContext.validate();
    
    //Get revocation status
    Boolean isRevoked = toValidateCertificateToken.isRevoked();
    RevocationToken revocationToken = toValidateCertificateToken.getRevocationToken();
    
    0 讨论(0)
提交回复
热议问题