Thứ Hai, 15 tháng 10, 2018

Test Verify Cert Chain Java

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package test.zmp.api;

import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.security.InvalidKeyException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.PublicKey;
import java.security.Signature;
import java.security.SignatureException;
import java.security.cert.CertificateEncodingException;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.security.interfaces.RSAPublicKey;
import java.util.Arrays;
import java.util.Collection;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509TrustManager;

/**
 *
 * @author chieuvh
 */
public class TestCert {

    public static void main(String[] args) throws Exception {
        InputStream inputStream = new FileInputStream("/zserver/data/cert.zing.vn");
        Collection<X509Certificate> x509CertificateZing = getCertificateFromStream(inputStream);
        printCertificate(x509CertificateZing);
        InputStream inputStreamDigi = new FileInputStream("/zserver/data/DigiCertSHA2HighAssuranceServerCA.crt");
        Collection<X509Certificate> x509CertificateDigi = getCertificateFromStream(inputStreamDigi);
        printCertificate(x509CertificateDigi);
        InputStream inputStreamRoot = new FileInputStream("/zserver/data/BuiltinObjectToken_DigiCertHighAssuranceEVRootCA.crt");
        Collection<X509Certificate> x509CertificateRoot = getCertificateFromStream(inputStreamRoot);
        printCertificate(x509CertificateRoot);
        System.out.println("==============================");
//        for (X509Certificate x509CertificateParent : x509CertificateDigi) {
//            for (X509Certificate x509CertificateChildren : x509CertificateZing) {
//                x509CertificateChildren.getSigAlgName();
//                Signature signer = Signature.getInstance(x509CertificateChildren.getSigAlgName());
//                signer.initVerify(x509CertificateParent.getPublicKey());
//                signer.update(x509CertificateChildren.getTBSCertificate());
//                boolean verifyResult = signer.verify(x509CertificateChildren.getSignature());
//                System.out.println("verifyResult " + verifyResult);
//            }
//        }
//        for (X509Certificate x509CertificateParent : x509CertificateRoot) {
//            for (X509Certificate x509CertificateChildren : x509CertificateDigi) {
//                x509CertificateChildren.getSigAlgName();
//                Signature signer = Signature.getInstance(x509CertificateChildren.getSigAlgName());
//                signer.initVerify(x509CertificateParent.getPublicKey());
//                signer.update(x509CertificateChildren.getTBSCertificate());
//                boolean verifyResult = signer.verify(x509CertificateChildren.getSignature());
//                System.out.println("verifyResult " + verifyResult);
//            }
//        }
        verifySign(x509CertificateRoot, x509CertificateDigi);
        verifySign(x509CertificateDigi, x509CertificateZing);
        verifySign(x509CertificateRoot, x509CertificateRoot);//self signed
        verifySign(x509CertificateRoot, x509CertificateZing);// will false
        TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
        trustManagerFactory.init((KeyStore) null);
// you could use a non-default KeyStore as your truststore too, instead of null.

//        for (TrustManager trustManager : trustManagerFactory.getTrustManagers()) {
//            if (trustManager instanceof X509TrustManager) {
//                X509TrustManager x509TrustManager = (X509TrustManager) trustManager;
//                X509Certificate[] x509Certificates = x509TrustManager.getAcceptedIssuers();
//                printCertificate(Arrays.asList(x509Certificates));
//            }
//        }
    }

    public static void printCertificate(Collection<X509Certificate> x509Certificates) throws Exception {
        for (X509Certificate x509Certificate : x509Certificates) {

            System.out.println("=========================");
//                    System.out.println("getVersion " + x509Certificate.getVersion());
//                    System.out.println("getSerialNumber " + x509Certificate.getSerialNumber());
//            x509Certificate.checkValidity();
            System.out.println("getIssuerDN " + x509Certificate.getIssuerDN().getName());
            System.out.println("getSubjectDN " + x509Certificate.getSubjectDN().getName());
            System.out.println("getPublicKey().getAlgorithm " + x509Certificate.getPublicKey().getAlgorithm());
            System.out.println("getPublicKey().getFormat " + x509Certificate.getPublicKey().getFormat());
            System.out.println("getSigAlgName " + (x509Certificate.getSigAlgName()));
            System.out.println("getEncoded " + Base64.encode(x509Certificate.getEncoded()));
            System.out.println("getPublicKey " + printHex(x509Certificate.getPublicKey().getEncoded()));
            System.out.println("getSignature " + printHex(x509Certificate.getSignature()));
//            calculateFingerPrint((RSAPublicKey)x509Certificate.getPublicKey());
//            System.out.println("SHA-1: " + generateFingerPrint(x509Certificate, "SHA-1"));
            System.out.println("SHA-256: " + generateFingerPrint(x509Certificate, "SHA-256"));
//                    x509Certificate.verify(x509Certificate.getPublicKey());
//                    System.out.println("getSubjectX500Principal " + (x509Certificate.getSubjectX500Principal().getName()));
//                    System.out.println("getSignature " + new String(x509Certificate.getSignature()));
//                    System.out.println("getPublicKey " + (x509Certificate.getPublicKey().toString()));
//            break;
        }
    }

    public static void verifySign(Collection<X509Certificate> x509CertificateRoot, Collection<X509Certificate> x509CertificateIntermediate) throws NoSuchAlgorithmException, InvalidKeyException, CertificateEncodingException, SignatureException {
        for (X509Certificate x509CertificateParent : x509CertificateRoot) {
            for (X509Certificate x509CertificateChildren : x509CertificateIntermediate) {
                x509CertificateChildren.getSigAlgName();
                Signature signer = Signature.getInstance(x509CertificateChildren.getSigAlgName());
                signer.initVerify(x509CertificateParent.getPublicKey());
                signer.update(x509CertificateChildren.getTBSCertificate());
                boolean verifyResult = signer.verify(x509CertificateChildren.getSignature());
                System.out.println("verifyResult " + verifyResult);
            }
        }
    }

    public static Collection<X509Certificate> getCertificateFromStream(InputStream stream) throws CertificateException {
        Collection<X509Certificate> certs = null;

        // Create a Certificate Factory
        CertificateFactory cf = CertificateFactory.getInstance("X.509");

        // Read the Trust Certs
        certs = (Collection<X509Certificate>) cf.generateCertificates(stream);

        return certs;
    }

    public static String generateFingerPrint(X509Certificate cert, String algorithm) throws CertificateEncodingException, NoSuchAlgorithmException {

        MessageDigest digest = MessageDigest.getInstance(algorithm);
        byte[] hash = digest.digest(cert.getEncoded());
        return printHex(hash);
//        final char delimiter = ':';
//
//        final int len = hash.length * 2 + hash.length - 1;
//        // Typically SHA-1 algorithm produces 20 bytes, i.e. len should be 59
//        StringBuilder fingerprint = new StringBuilder(len);
//
//        for (int i = 0; i < hash.length; i++) {
//            // Step 1: unsigned byte
//            hash[i] &= 0xff;
//
//            // Steps 2 & 3: byte to hex in two chars
//            // Lower cased 'x' at '%02x' enforces lower cased char for hex value!
//            fingerprint.append(String.format("%02x", hash[i]));
//
//            // Step 4: put delimiter
//            if (i < hash.length - 1) {
//                fingerprint.append(delimiter);
//            }
//        }
//
//        return fingerprint.toString();

    }

    public static String printHex(byte[] bytes) {
        final char delimiter = ':';

        final int len = bytes.length * 2 + bytes.length - 1;
        // Typically SHA-1 algorithm produces 20 bytes, i.e. len should be 59
        StringBuilder fingerprint = new StringBuilder(len);

        for (int i = 0; i < bytes.length; i++) {
            // Step 1: unsigned byte
            bytes[i] &= 0xff;

            // Steps 2 & 3: byte to hex in two chars
            // Lower cased 'x' at '%02x' enforces lower cased char for hex value!
            fingerprint.append(String.format("%02x", bytes[i]));

            // Step 4: put delimiter
            if (i < bytes.length - 1) {
                fingerprint.append(delimiter);
            }
        }

        return fingerprint.toString();
    }

}