package org.liuy.bouncycastle;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.math.BigInteger;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.PrivateKey;
import java.security.SignatureException;
import java.security.cert.CRLException;
import java.security.cert.CertificateFactory;
import java.security.cert.CertificateParsingException;
import java.security.cert.X509CRL;
import java.security.cert.X509CRLEntry;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import javax.security.auth.x500.X500PrivateCredential;
import org.apache.log4j.Logger;
import org.bouncycastle.asn1.x509.CRLNumber;
import org.bouncycastle.asn1.x509.CRLReason;
import org.bouncycastle.asn1.x509.X509Extensions;
import org.bouncycastle.x509.X509V2CRLGenerator;
import org.bouncycastle.x509.extension.AuthorityKeyIdentifierStructure;
import org.liuy.security.cert.CertificateCoder;
import org.liuy.security.cert.KeyStoreSeal;
import org.liuy.utils.StringUtil;
/**
* CRL列表操作,包含:
* 1 创建
* 2 删除
* 3 读取
*/
public abstract class X509_Crl {
private final static Logger logger = Logger.getLogger(X509_Crl.class.getName ()) ;
/**
* 创建CRL列表。
* list数组可使用addSerialList进行添加
* @param caCert: CRL签名者证书
* @param caKey: CRL签名者私钥
* @param list: 被废除证书序列号数组
*
*/
public static X509CRL createCRL(
X509Certificate caCert,
PrivateKey caKey,
List list)
{
//crl版本
X509V2CRLGenerator crlGen = new X509V2CRLGenerator();
Date now = new Date();
crlGen.setIssuerDN(caCert.getSubjectX500Principal());
//更新时间
crlGen.setThisUpdate(now);
//下一次更新时间
crlGen.setNextUpdate(new Date(now.getTime() + 24*60*60*1000));
//签名算法
crlGen.setSignatureAlgorithm("SHA1WithRSAEncryption");
//证书废除原因
if(list!=null)
{
Iterator it = list.iterator();
while (it.hasNext())
{
BigInteger br=(BigInteger) it.next();
crlGen.addCRLEntry(br, now, CRLReason.privilegeWithdrawn);
}
}
//扩展项
try {
crlGen.addExtension(X509Extensions.AuthorityKeyIdentifier,
false, new AuthorityKeyIdentifierStructure(caCert));
crlGen.addExtension(X509Extensions.CRLNumber,
false, new CRLNumber(BigInteger.valueOf(1)));
X509CRL crl=crlGen.generateX509CRL(caKey, "BC");
crl.verify(caCert.getPublicKey(),"BC");
return crl;
} catch (CertificateParsingException e) {
logger.error("添加扩展项失败"+e.getMessage());
} catch (InvalidKeyException e) {
logger.error("生成crl失败"+e.getMessage());
} catch (NoSuchProviderException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
} catch (SignatureException e) {
e.printStackTrace();
} catch (CRLException e) {
logger.error("验证crl失败"+e.getMessage());
} catch (NoSuchAlgorithmException e) {
logger.error("验证crl失败"+e.getMessage());
}
return null;
}
/**
* 加载CRL证书吊销列表文件
* @param crlFilePath
* @return
* @throws Exception
*/
public static X509CRL loadX509CRL(String crlFilePath) throws Exception {
FileInputStream in = new FileInputStream(crlFilePath);
CertificateFactory cf = CertificateFactory.getInstance("X.509");
X509CRL crl = (X509CRL)cf.generateCRL(in);
in.close();
return crl;
}
/**
* 加载证书CLR列表
* @param X509Certificate
* 证书对象
*/
public static List addSerialList(X509Certificate x509)
{
List<BigInteger> list=new ArrayList<BigInteger>();
list.add(x509.getSerialNumber());
return list;
}
/**
* 验证证书是否在CRL中。
* @param X509CRL
* crl对象
* @param X509Certificate
* 证书对象
* @throws IOException
*/
private static X509CRLEntry isRevoked(X509CRL crl,BigInteger br) throws IOException
{
X509CRLEntry set =crl.getRevokedCertificate(br);
if(set!=null)
{
return set;
}
else
{
return null;
}
}
/**
* 验证证书是否在CRL中。
* @param X509CRL
* crl对象
* @param X509Certificate
* 证书对象
* @throws IOException
*/
public static X509CRLEntry isRevoked(X509CRL crl,X509Certificate x509) throws IOException
{
BigInteger br=x509.getSerialNumber();
return isRevoked(crl,br);
}
/**
* 验证证书是否在CRL中。
* @param X509CRL
* crl对象
* @param X509Certificate
* 证书对象
* @throws IOException
*/
public static X509CRLEntry isRevoked(X509CRL crl,String serialNumber) throws IOException
{
BigInteger br=new BigInteger(StringUtil.replaceBlank(serialNumber),16);
return isRevoked(crl,br);
}
/**
* 统计crl总数
* @param X509CRL
* crl对象
* @throws IOException
*
*/
public static int num(X509CRL crl) throws IOException
{
Set set =crl.getRevokedCertificates();
Iterator it=set.iterator();
int i=0;
while(it.hasNext())
{
it.next();
i++;
}
return i;
}
public static void main(String[] args) throws Exception
{
// PropertiesConf jc=new PropertiesConf();
// jc.setPara();
BC.setBC();
String rootPath="E:\\root";
//获取二级证书公钥和私钥
X500PrivateCredential x500=KeyStoreSeal.getX500Private(rootPath, "123456", "inter");
List<BigInteger> list=new ArrayList<BigInteger>();
//被注销的用户
X509Certificate x1=(X509Certificate) CertificateCoder.getCertificate("c:/1.cer");
list.add(x1.getSerialNumber());
X509CRL crl=createCRL(x500.getCertificate(),x500.getPrivateKey(),list);
FileOutputStream fOut = new FileOutputStream("c:/test.crl");
fOut.write(crl.getEncoded());
fOut.close();
//加载证书黑名单
// X509CRL crl=loadX509CRL("c:/05.17.crl");
// int i=num(crl);
// System.out.println(i);
}
}