USBKEY全解析---证书生产(java)


package org.liuy.bouncycastle;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.math.BigInteger;
import java.security.KeyPair;
import java.security.KeyStore;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.cert.Certificate;
import java.security.cert.X509Certificate;
import java.util.Date;
import java.util.Vector;

import org.apache.commons.io.FileUtils;
import org.apache.log4j.Logger;
import org.bouncycastle.asn1.DERBMPString;
import org.bouncycastle.asn1.DERIA5String;
import org.bouncycastle.asn1.DERObjectIdentifier;
import org.bouncycastle.asn1.DERSequence;
import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
import org.bouncycastle.asn1.x509.BasicConstraints;
import org.bouncycastle.asn1.x509.DistributionPoint;
import org.bouncycastle.asn1.x509.DistributionPointName;
import org.bouncycastle.asn1.x509.ExtendedKeyUsage;
import org.bouncycastle.asn1.x509.GeneralName;
import org.bouncycastle.asn1.x509.GeneralNames;
import org.bouncycastle.asn1.x509.KeyPurposeId;
import org.bouncycastle.asn1.x509.KeyUsage;
import org.bouncycastle.asn1.x509.X509Extensions;
import org.bouncycastle.jce.PrincipalUtil;
import org.bouncycastle.jce.X509Principal;
import org.bouncycastle.jce.interfaces.PKCS12BagAttributeCarrier;
import org.bouncycastle.x509.X509V3CertificateGenerator;
import org.bouncycastle.x509.extension.AuthorityKeyIdentifierStructure;
import org.bouncycastle.x509.extension.SubjectKeyIdentifierStructure;
import org.liuy.certdn.form.KeyUseForm;
import org.liuy.conf.IConf;
import org.liuy.security.cert.KeyStoreSeal;

/**
 *  
 *  创建p12证书文件。默认密码:123456
 *  @author Liuy
 *  @version 2010-07-19
 *  
 */
public class CretPKCS12 {

	private static char[] passwd = "123456".toCharArray();
	private static X509V3CertificateGenerator v3CertGen = new X509V3CertificateGenerator();
	private final	static Logger logger = Logger.getLogger(CretPKCS12.class.getName ());
    
	
	/**
     * 创建根证书
     */
    private static Certificate createMasterCert(
            PublicKey pubKey,
            PrivateKey privKey)
            throws Exception {

    	  String subjectDN = "CN=FT_ROOT,O=ROOT,C=CN";
    	  v3CertGen.reset();
          v3CertGen.setSerialNumber(BigInteger.valueOf(System.currentTimeMillis()));
          v3CertGen.setIssuerDN(new X509Principal(subjectDN));  
          v3CertGen.setNotBefore(new Date(System.currentTimeMillis()));
          v3CertGen.setNotAfter(new Date(System.currentTimeMillis() + 1000L*60*60*24*30*12*10));
          v3CertGen.setSubjectDN(new X509Principal(subjectDN));
          v3CertGen.setPublicKey(pubKey);
          v3CertGen.setSignatureAlgorithm("SHA256WithRSAEncryption");
          //使用者密钥标示符号
          v3CertGen.addExtension(X509Extensions.SubjectKeyIdentifier,false,
                new SubjectKeyIdentifierStructure(pubKey));
          //颁发机构密钥标示符
          v3CertGen.addExtension(X509Extensions.AuthorityKeyIdentifier,false,
                new AuthorityKeyIdentifierStructure(pubKey));
          //基本路径限制
          v3CertGen.addExtension(X509Extensions.BasicConstraints,true,
                new BasicConstraints(true));
          //密钥用法
          v3CertGen.addExtension(X509Extensions.KeyUsage,true, new KeyUsage(
  				KeyUsage.keyCertSign | KeyUsage.cRLSign));  
          X509Certificate cert = v3CertGen.generate(privKey);
          cert.checkValidity(new Date());
          cert.verify(pubKey);
          PKCS12BagAttributeCarrier bagAttr = (PKCS12BagAttributeCarrier) cert;

          //证书链名称
          bagAttr.setBagAttribute(PKCSObjectIdentifiers.pkcs_9_at_friendlyName,new DERBMPString("FT_ROOT"));
          return cert;
    }
    
    /**
     * 
     * 创建二级证书
     * @param pubKey  二级证书公钥
     * @param caPrivKey  根证书私钥
     * @param caCert 根证书
     */
    private static Certificate createIntermediateCert(
            PublicKey pubKey,
            PrivateKey caPrivKey,
            X509Certificate caCert)
            throws Exception {
    	
    	  String subjectDN = "CN=FT_CA,O=CA,C=CN";
    	  v3CertGen.reset();
          v3CertGen.setSerialNumber(BigInteger.valueOf(System.currentTimeMillis()));
          v3CertGen.setIssuerDN(new X509Principal(PrincipalUtil.getSubjectX509Principal(caCert)));  
          v3CertGen.setNotBefore(new Date(System.currentTimeMillis()));
          v3CertGen.setNotAfter(new Date(System.currentTimeMillis() + 1000L*60*60*24*30*12*5));
          v3CertGen.setSubjectDN(new X509Principal(subjectDN));
          v3CertGen.setPublicKey(pubKey);
          v3CertGen.setSignatureAlgorithm("SHA256WithRSAEncryption");
          //使用者密钥标示符号
          v3CertGen.addExtension(X509Extensions.SubjectKeyIdentifier,false,
                new SubjectKeyIdentifierStructure(pubKey));
          //颁发机构密钥标示符
          v3CertGen.addExtension(X509Extensions.AuthorityKeyIdentifier,false,
                new AuthorityKeyIdentifierStructure(caCert));
          //基本路径限制
          v3CertGen.addExtension(X509Extensions.BasicConstraints,true,
                new BasicConstraints(true));
          //密钥用法
          v3CertGen.addExtension(X509Extensions.KeyUsage,true, new KeyUsage(
  				KeyUsage.keyCertSign | KeyUsage.cRLSign));
          
          X509Certificate cert = v3CertGen.generate(caPrivKey);
          cert.checkValidity(new Date());
          cert.verify(caCert.getPublicKey());
          PKCS12BagAttributeCarrier bagAttr = (PKCS12BagAttributeCarrier) cert;

        //证书链名称
          bagAttr.setBagAttribute(PKCSObjectIdentifiers.pkcs_9_at_friendlyName,new DERBMPString("CFCA FEITIAN TEST"));
          return cert;
    }

    /**
     * 创建证书
     * @param pubKey 证书公钥
     * @param IntermePrivKey 二级证书私钥
     * @param IntermeCert 二级证书对象
     * @param subjectDN  证书DN项
     * @param keyUseForm 证书的附属信息
     */
    public static Certificate createCert(
            PublicKey pubKey,
            PrivateKey IntermePrivKey,
            X509Certificate IntermeCert,
            String subjectDN,KeyUseForm keyUseForm)
            throws Exception {
    	
        //创建V3证书
        v3CertGen.reset();
        v3CertGen.setSerialNumber(BigInteger.valueOf(System.currentTimeMillis()));
        v3CertGen.setIssuerDN(new X509Principal(PrincipalUtil.getSubjectX509Principal(IntermeCert)));  
        v3CertGen.setNotBefore(new Date(System.currentTimeMillis()));
        v3CertGen.setNotAfter(new Date(System.currentTimeMillis()+1000L*60*60*24*30*12));
//      v3CertGen.setNotBefore(ProAssistant.getNormatTiem("2010-08-10 10:00:00"));
//      v3CertGen.setNotAfter(ProAssistant.getNormatTiem("2010-09-10 10:00:00"));
        v3CertGen.setSubjectDN(new X509Principal(subjectDN));
        v3CertGen.setPublicKey(pubKey);
        v3CertGen.setSignatureAlgorithm(keyUseForm.getCertSignAlgo());
        

        //创建扩展项
        /*
         *SubjectKeyIdentifier:主体密钥标识符:
         *   本项提供一种识别包含有一个特定公钥的证书的方法。
         *   此扩展标识了被认证的公开密钥,它能够区分同一主体使用的不同密钥。
         *   对于使用密钥标识符的主体的各个密钥标识符而言,每一个密钥标识符均应是唯一的。
         *   CA签发证书时必须把CA证书中本扩展的值赋给终端实体证书AuthorityKeyIdentifier扩展中的KeyIdentifier项。
         *   CA证书的主体密钥标识符应从公钥中或者生成唯一值的方法中导出。终端实体证书的主体密钥标识符应从公钥中导出。
         *	 所有的CA证书必须包括本扩展,此扩展项为非关键项。
         *
         */
        v3CertGen.addExtension(X509Extensions.SubjectKeyIdentifier,false,
        		new SubjectKeyIdentifierStructure(pubKey));
        /* 
        *AuthorityKeyIdentifier:密钥扩展项
        *	
        *  有多张根证书时区分签发证书
		*
        */
        v3CertGen.addExtension(X509Extensions.AuthorityKeyIdentifier,false,
                new AuthorityKeyIdentifierStructure(IntermeCert));
        
        /* 
         *  证书支持多域名
 		 *
        ASN1EncodableVector sanVector = new ASN1EncodableVector();
        sanVector.add(new GeneralName(GeneralName.dNSName,"localhost"));
        sanVector.add(new GeneralName(GeneralName.dNSName,"192.168.35.13"));
        sanVector.add(new GeneralName(GeneralName.dNSName,"127.0.0.1"));
        sanVector.add(new GeneralName(GeneralName.rfc822Name,"liuy@test.test"));
        DERSequence san = new DERSequence(sanVector);   
        GeneralNames subjectAltName = new GeneralNames(san);  
        v3CertGen.addExtension(X509Extensions.SubjectAlternativeName,false,
        		subjectAltName);
        
        */
         
        int keyUse=0;
        if(keyUseForm.isSignUse())
        {
        	//签名用法
        	keyUse=KeyUsage.digitalSignature | KeyUsage.nonRepudiation;
        }
        if(keyUseForm.isEncUse())
        {
        	//加密用法
        	keyUse+=KeyUsage.keyEncipherment | KeyUsage.keyAgreement;
        }
        if(keyUse!=0)
        {
            v3CertGen.addExtension(X509Extensions.KeyUsage, true, new KeyUsage( keyUse ));
        }
        
        boolean flag=false;
        /* 
         *  扩展密钥标识符
 		 *
         */
        Vector<DERObjectIdentifier> extendedKeyUsageV = new Vector<DERObjectIdentifier>();
//		extendedKeyUsageV.add(KeyPurposeId.id_kp_serverAuth);
//		extendedKeyUsageV.add(KeyPurposeId.id_kp_clientAuth);
		//时间戳增强密钥用法
        if(keyUseForm.isTsaUse())
        {
        	extendedKeyUsageV.add(KeyPurposeId.id_kp_timeStamping);
        	flag=true;
        }
		//邮件证书
        if(keyUseForm.isEMailUse())
        {
        	extendedKeyUsageV.add(KeyPurposeId.id_kp_emailProtection);
        	flag=true;
        }
//		extendedKeyUsageV.add(new KeyPurposeId("1.2.840.113583.1.1.5"));
        
        
       //代码签名证书
        if(keyUseForm.isCodeSign())
        {
            extendedKeyUsageV.add(new KeyPurposeId("1.3.6.1.5.5.7.3.3"));
            flag=true;
        }
        
        //加入扩展秘钥
        if(flag)
        {
    		v3CertGen.addExtension(X509Extensions.ExtendedKeyUsage, true,
			new ExtendedKeyUsage(extendedKeyUsageV));
        }

        
        /* 
         * 证书基本限制
         * 证书路径:
         * new BasicConstraints(true, 0));
         * 1 true代表该证书后 最多的证书链
         * 2 false  公钥不能验证其他证书
         */
        v3CertGen.addExtension(X509Extensions.BasicConstraints,true,
                new BasicConstraints(false));
        
        /*
         * CRL发布点
         *  
         */
        if(keyUseForm.getCrlDL()!=null)
        {
            GeneralName gn = new GeneralName(GeneralName.uniformResourceIdentifier, new DERIA5String(keyUseForm.getCrlDL()));
    		GeneralNames gns = new GeneralNames(new DERSequence(gn));
    		DistributionPointName dpn = new DistributionPointName(0, gns);
    		DistributionPoint distp = new DistributionPoint(dpn, null, null);
    		v3CertGen.addExtension(
    				X509Extensions.CRLDistributionPoints, false,
    				new DERSequence(distp));
        }

//        v3CertGen.addExtension(MiscObjectIdentifiers.netscapeCertType,false,
//                new NetscapeCertType(NetscapeCertType.objectSigning | NetscapeCertType.smime));
        
        //创建并验证信息
        X509Certificate cert = v3CertGen.generate(IntermePrivKey,"BC");
        cert.checkValidity(new Date());
        cert.verify(IntermeCert.getPublicKey());
        PKCS12BagAttributeCarrier bagAttr = (PKCS12BagAttributeCarrier) cert;
        //创建证书链名称
        bagAttr.setBagAttribute(PKCSObjectIdentifiers.pkcs_9_at_friendlyName,
                new DERBMPString("User"));
//        bagAttr.setBagAttribute(PKCSObjectIdentifiers.pkcs_9_at_localKeyId,
//                new SubjectKeyIdentifierStructure(pubKey));
        return cert;
    }
    
    /**
     * 创建root证书KeyStore
     * @param outPath KeyStore输出路径
     * @throws Exception 
     */
    private static void createRootKeyStore(String outPath) throws Exception
    {
    	BC.setBC();
	    //ca  keys
		KeyPair capair = Utils.generateRSAKeyPair(2048);	
	    //intermediate   keys
		KeyPair intermediatepair = Utils.generateRSAKeyPair(2048);
	    //根证书
		PrivateKey caPrivKey = capair.getPrivate();
		PublicKey caPubKey = capair.getPublic();
		//二级证书
		PrivateKey intPrivKey = intermediatepair.getPrivate();
		PublicKey intPubKey = intermediatepair.getPublic();

		//创建证书链
		Certificate[] root = new Certificate[1];
		Certificate[] Inter = new Certificate[1];
		//根证书
		root[0] = createMasterCert(caPubKey, caPrivKey);
		//二级证书
		Inter[0] = createIntermediateCert(intPubKey, caPrivKey, (X509Certificate) root[0]);
		//输出根证书与二级证书
		KeyStore store = KeyStore.getInstance("JKS");
		store.load(null,null);
		store.setKeyEntry("root", caPrivKey, passwd, root);
		store.setKeyEntry("inter", intPrivKey, passwd, Inter);
		FileOutputStream out = new FileOutputStream(outPath);
		store.store(out, passwd);
		out.close();
    }
      
    /**
     * 创建 P12证书
     * @param subjectDN  证书DN项,形式如:"C=CN,O=Test,OU=Liuy,oid.2.5.4.1=1234"
     * @throws Exception 
     */
    public static byte[] createP12Cert(String subjectDN,KeyUseForm keyUseForm) 
    {
    	BC.setBC();
    	ByteArrayOutputStream baos = new ByteArrayOutputStream(); 
    	try {
			KeyPair personalpair = Utils.generateRSAKeyPair(keyUseForm.getKeyLen());
			//个人
	        PrivateKey privKey = personalpair.getPrivate();
	        PublicKey pubKey = personalpair.getPublic();
	        //通过配置文件找到root文件路径
			String rootPath= IConf.getValue("rootPath");
			//获取二级证书公钥和私钥
			X509Certificate intCert = KeyStoreSeal.getX500Private(rootPath, "123456", "inter").getCertificate();
			PrivateKey intPrivKey = KeyStoreSeal.getX500Private(rootPath, "123456", "inter").getPrivateKey();
	        //制作证书
	        Certificate user=createCert(pubKey, intPrivKey,intCert, subjectDN,keyUseForm);	        
	        Certificate[] chain = new Certificate[1];
	        chain[0]=user;
	        KeyStore store = KeyStore.getInstance("PKCS12", "BC");
	        store.load(null, null);
//	        String s=StringUtil.getOneKey(subjectDN, "CN");
	        store.setKeyEntry("", privKey, null, chain);
	        store.store(baos, passwd);
	        return baos.toByteArray();
		} catch (Exception e) {
			logger.error("参数证书错误",e);
		}
		 finally
		{
			 try {
				baos.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return null;	
    }
    
    
    public static void main(String[] args) throws Exception 
    {
//     	createRootKeyStore("d:/root");
    	
    	String subjectDN="C=CN";	
		KeyUseForm keyUseForm =new KeyUseForm();
		keyUseForm.setKeyLen(1024);
		keyUseForm.setCrlDL("http://liuy/crl.crl");
		keyUseForm.setSignUse(true);
		keyUseForm.setEncUse(true);
		keyUseForm.setTsaUse(true);
		keyUseForm.setCertSignAlgo("SHA1WithRSAEncryption");
    	byte[] certBy=createP12Cert(subjectDN,keyUseForm);
    	
    	File f=new File("d:/2.pfx");
    	FileUtils.writeByteArrayToFile(f, certBy);
    }
}

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值