Java BouncyCastle API 创建证书撤销列表 CRL 和验证证书有效性

创建 CRL 需要用到有 CRL 权限的 CA 机构私钥和证书:

        Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
		// 准备好创建 CRL 所需的私钥和证书
        PrivateKey caPrivateKey = ......
        X509Certificate caCertificate = ......

        X509v2CRLBuilder crlBuilder = new X509v2CRLBuilder(
                new X500Name(caCertificate.getSubjectDN().getName()),
                new Date()
        );
        crlBuilder.setNextUpdate(new Date(System.currentTimeMillis() + 86400 * 1000)); // 1 天有效期

		crlBuilder.addCRLEntry(111/*被撤销证书序列号*/, new Date() /*被撤销时间*/, 1 /*被撤销原因*/);

        JcaContentSignerBuilder contentSignerBuilder = new JcaContentSignerBuilder("SHA256WithRSA");
        contentSignerBuilder.setProvider("BC");
        X509CRLHolder crlHolder = crlBuilder.build(contentSignerBuilder.build(caPrivateKey));
        JcaX509CRLConverter converter = new JcaX509CRLConverter();
        converter.setProvider("BC");
        X509CRL crl = converter.getCRL(crlHolder);

根证书创建方法可以看:根据 CSR 创建证书。

撤销证书时需要指定撤销原因,有以下几种:

原因 说明
unspecified 未指定
keyCompromise 私钥泄漏
cACompromise CA 私钥可能泄漏
affiliationChanged 组织变化,隶属关系变更
superseded 被取代
cessationOfOperation CA 停用
certificateHold 临时吊销
removeFromCRL 使用 certificateHold 吊销的证书,可以用 removeFromCRL 取消吊销
privilegeWithdrawn 因证书某权限被撤销而吊销
aACompromise indicates that it is known or suspected that aspects of the AA validated in the attribute certificate have been compromised

如果验证一个证书是否在 CRL 撤销列表里呢?

		// 读取 CRL 对象
		X509CRL x509CRL = ......
		// 读取签发 CRL 的公钥,一般签发 CRL 的公钥和签发证书的公钥是相同的
        PublicKey publicKey = ......
        // 验证 CRL 合法性
        x509CRL.verify(publicKey);
        // 读取待验证的证书
        X509Certificate certificate = ......
        // 验证该证书是否被撤销
        boolean isRevoked = x509CRL.isRevoked(certificate);

isRevoked 方法具体做了哪些事呢?可以看下 X509CRLImpl 里的实现:

  1. 判断证书类型是否是 X.509
  2. 判断证书序列号是否在 CRL 里
  3. 判断证书签发者和 CRL 签发者是否是同一个
public boolean isRevoked(Certificate var1) {
        if (!var1.getType().equals("X.509")) {
            throw new IllegalArgumentException("X.509 CRL used with non X.509 Cert");
        } else {
            Enumeration var2 = this.c.getRevokedCertificateEnumeration();
            X500Name var3 = this.c.getIssuer();
            if (var2.hasMoreElements()) {
                BigInteger var4 = ((X509Certificate)var1).getSerialNumber();

                while(var2.hasMoreElements()) {
                    CRLEntry var5 = CRLEntry.getInstance(var2.nextElement());
                    if (this.isIndirect && var5.hasExtensions()) {
                        Extension var6 = var5.getExtensions().getExtension(Extension.certificateIssuer);
                        if (var6 != null) {
                            var3 = X500Name.getInstance(GeneralNames.getInstance(var6.getParsedValue()).getNames()[0].getName());
                        }
                    }

                    if (var5.getUserCertificate().hasValue(var4)) {
                        X500Name var9;
                        if (var1 instanceof X509Certificate) {
                            var9 = X500Name.getInstance(((X509Certificate)var1).getIssuerX500Principal().getEncoded());
                        } else {
                            try {
                                var9 = org.bouncycastle.asn1.x509.Certificate.getInstance(var1.getEncoded()).getIssuer();
                            } catch (CertificateEncodingException var8) {
                                throw new IllegalArgumentException("Cannot process certificate: " + var8.getMessage());
                            }
                        }

                        if (!var3.equals(var9)) {
                            return false;
                        }

                        return true;
                    }
                }
            }
            return false;
        }
    }

你可能感兴趣的:(安全,Java,ssl,PKI,java)