获取数字证书相关信息,证书链有效性验证,RSA加密和解密功能之证书链有效性验证

 /**
     * 证书有效性验证,后台将证书链以byte[]数组集合的形式传入
     * @param certChain 后台传入的证书链
     * @param cert2Verify 本地需要验证的证书
     * @return
     */
    public int certificateValidate(List<byte[]> certChain, byte[] cert2Verify) {
        List<X509Certificate> certss = new ArrayList<>();
        CertificateFactory certificatefactory;
        X509Certificate cert;
        InputStream input;
        try {
            certificatefactory = CertificateFactory.getInstance("X.509");
//转换为inputstream,并将此inputstream转为X509Certificate的类型加入到list集合中,用于后续的
//排序
            input = new ByteArrayInputStream(cert2Verify);
            cert = (X509Certificate) certificatefactory.generateCertificate(input);
            certss.add(cert);
//将证书链中的每一层节点转换为X509Certificate类型并加入到集合中
            for (byte[] b : certChain) {
                input = new ByteArrayInputStream(b);
                cert = (X509Certificate) certificatefactory.generateCertificate(input);
                certss.add(cert);
            }
            //排序,为什么需要排序?因为后台传入过来的证书链并不一定是按照验证顺序进行排序的,
//所以需要进行排序后验证
            List<X509Certificate> certs = order(certss);
//进行长度判断,如果验证证书链排序过程中,出现问题直接验证失败
            if (certs.size() != certss.size()) {
                Log.e("123", "证书链校验失败");
                return 1;
            }
            //验证
            verifyCerts(certs);
            Log.e("123", "证书验证成功");
            return 0;
        } catch (CertificateException e) {
            e.printStackTrace();
            Log.e("123", "证书无效");
            return 1;
        } catch (Exception e) {
            e.printStackTrace();
            Log.e("123", "证书无效");
            return 0;
        }

    }

    /**
     * 找到证书父节点
     * @param parents
     * @param child
     * @return
     */
    private X509Certificate findParent(List<X509Certificate> parents, X509Certificate child) {
//获取到需要找到父节点证书的颁布者
        Principal p = child.getIssuerDN();
        Principal subjectDN = child.getSubjectDN();
//如果证书的颁发者与颁发给是一样的,说明此证书没有父节点,为最外层证书
        if (p.equals(subjectDN)) {
            return null;
        }


        for (int i = 0; i < parents.size(); i++) {
            X509Certificate parent = parents.get(i);
            if (p.equals(parent.getSubjectDN())) {
                return parent;
            }
        }
        return null;
    }

    /**
     * 排序
     * @param certss
     * @return
     */
    private List<X509Certificate> order(List<X509Certificate> certss) {
        List<X509Certificate> certInOder = new ArrayList<>();
        X509Certificate cert2Verify = certss.get(0);
        certInOder.add(cert2Verify);
        for (int i = 0; i < certss.size(); i++) {
//找到父节点
            X509Certificate parent = findParent(certss, cert2Verify);
            if (parent == null) {
                break;
            } else {
//找到父节点证书后加入到集合中,并把找到的证书作为子证书,去寻找它的父节点
                certInOder.add(parent);
                cert2Verify = parent;
            }
        }
        return certInOder;
    }

    /**
     * 证书有效性验证
     * @param certs
     * @throws Exception
     */
    private static void verifyCerts(List<X509Certificate> certs) throws Exception {
        int n = certs.size();
        for (int i = 0; i < n - 1; i++) {
            X509Certificate cert = certs.get(i);
            X509Certificate issuer = (X509Certificate) certs.get(i + 1);
//验证,这里的验证需要是排序好的
            cert.verify(issuer.getPublicKey());
        }
//自己验证自己,此步可以不要
        X509Certificate last = (X509Certificate) certs.get(n - 1);
        last.verify(last.getPublicKey());
    }

验证代码示例:

  private String getKeyFromCRT() {
        Log.e("===========PublicKey", "getKeyFromCRT()");
        String key = "";
//        String key1 = "";
        CertificateFactory certificatefactory;
        X509Certificate Cert;
        InputStream bais;
        InputStream bais1;
        InputStream bais2;

        PublicKey pk1;
        try {
           
            certificatefactory = CertificateFactory.getInstance("X.509");
            //读取放在项目中assets文件夹下的.crt文件;你可以读取绝对路径文件下的crt,返回一个InputStream(或其子类)。
//证书链
            bais = getAssets().open("2.cer");
            bais1 = getAssets().open("1.cer");
//需要验证的证书
            bais2 = getAssets().open("cn.crt");
//将inputstream转换为byte数组
            List<byte[]> bytes = new ArrayList<>();
            ByteArrayOutputStream swapStream = new ByteArrayOutputStream();
            byte[] buff = new byte[100];
            int rc = 0;
            while ((rc = bais.read(buff, 0, 100)) > 0) {
                swapStream.write(buff, 0, rc);
            }
            byte[] b = swapStream.toByteArray();
//添加到集合
            bytes.add(b);


            ByteArrayOutputStream swapStre = new ByteArrayOutputStream();
            byte[] buff1 = new byte[100];
            int rc1 = 0;
            while ((rc1 = bais1.read(buff1, 0, 100)) > 0) {
                swapStre.write(buff1, 0, rc1);
            }
            byte[] b1 = swapStre.toByteArray();
            bytes.add(b1);


            ByteArrayOutputStream swapStre2 = new ByteArrayOutputStream();
            byte[] buff2 = new byte[100];
            int rc3 = 0;
            while ((rc3 = bais2.read(buff2, 0, 100)) > 0) {
                swapStre2.write(buff2, 0, rc3);
            }
            byte[] b3 = swapStre2.toByteArray();

            certificate.getCertificateInfo(b3);
//验证
            certificate.certificateValidate(bytes,b3);

猜你喜欢

转载自blog.csdn.net/KuangAnGuo/article/details/85614409