Get a Pentest and security assessment of your IT network.

Cyber Security

OpenSSL Verify with Bouncy Castle

TL;DR

This guide shows you how to replicate OpenSSL’s openssl verify functionality using the Bouncy Castle cryptography library in Java. This is useful when you need a pure-Java solution for certificate verification without relying on native OpenSSL libraries.

Prerequisites

  • Java Development Kit (JDK) installed
  • Bouncy Castle Provider JAR file added to your project’s classpath. Download from the Bouncy Castle website.

Steps

  1. Add the Bouncy Castle Provider
  2. First, you need to register the Bouncy Castle provider in your Java application. This tells Java to use Bouncy Castle’s cryptographic algorithms.

    Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
  3. Load the Certificate
  4. Load the certificate you want to verify from a file (e.g., PEM or DER format). Use a java.io.FileInputStream and a java.security.cert.CertificateFactory.

    FileInputStream fis = new FileInputStream("certificate.pem");
    CertificateFactory cf = CertificateFactory.getInstance("X.509");
    X509Certificate certificate = (X509Certificate) cf.load(fis);
    fis.close();
  5. Load the Trusted Root Certificates
  6. You’ll need to load the trusted root certificates that form your trust chain. This is often a CA bundle file.

    FileInputStream trustFis = new FileInputStream("truststore.pem");
    CertificateFactory trustCf = CertificateFactory.getInstance("X.509");
    List<X509Certificate> trustedCerts = (List<X509Certificate>>) trustCf.load(trustFis);
    trustFis.close();
  7. Create a Trust Manager
  8. Implement a custom TrustManager to handle the trusted certificates.

    class CustomTrustManager implements TrustManager {
        private final List<X509Certificate> trustedCerts;
    
        public CustomTrustManager(List<X509Certificate> trustedCerts) {
            this.trustedCerts = trustedCerts;
        }
    
        @Override
        public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
            // Implement your trust logic here.
            for (X509Certificate cert : chain) {
                if (!trustedCerts.contains(cert)) {
                    throw new CertificateException("Untrusted certificate");
                }
            }
        }
    
        @Override
        public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
           // Not used in this example.
        }
    
        @Override
        public X509Certificate[] getAcceptedIssuers() {
            return trustedCerts.toArray(new X509Certificate[0]);
        }
    }
    
  9. Create an SSLContext
  10. Create an SSLContext using the custom TrustManager.

    SSLContext sslContext = SSLContext.getInstance("TLS");
    sslContext.init(null, new TrustManager[]{new CustomTrustManager(trustedCerts)}, null);
    
  11. Verify the Certificate
  12. This step is where you actually verify the certificate against the trusted root certificates.

    X509CertChain chain = new X509CertChain(new java.util.ArrayList<X509Certificate>(java.util.Arrays.asList(certificate)));
    chain.validateAll(null, null);
    

    If the validation succeeds without throwing an exception, the certificate is considered valid.

  13. Handle Exceptions
  14. Catch CertificateException and other relevant exceptions to handle invalid certificates or trust chain issues. These exceptions indicate verification failures.

Related posts
Cyber Security

Zip Codes & PII: Are They Personal Data?

Cyber Security

Zero-Day Vulnerabilities: User Defence Guide

Cyber Security

Zero Knowledge Voting with Trusted Server

Cyber Security

ZeroNet: 51% Attack Risks & Mitigation