Java 生成数字证书系列(三)生成数字证书

来源:互联网 发布:nginx plus 和 nginx 编辑:程序博客网 时间:2024/05/21 22:53

from  http://blog.csdn.net/happylee6688/article/details/42266465


前两篇把基本的概念和构成都大致的说了一下,今天这篇文章,主要是讲一下,如何使用 Java 代码生成 CA 证书,以及在生成证书的时候,需要设置的一些属性。


正文


废话不多说,直接上内容。

这里使用的是 Java 的 api ,以及第三方的一个组件 —— BC,(Bouncy Castle)。稍微介绍一下 BC,Bouncy Castle 是一种用于 Java 平台的开放源码的轻量级密码术包。它支持大量的密码术算法,并提供 JCE 1.2.1 的实现。而我们将要使用的就是非常常用的非对称算法 RSA 加密算法。

下面我们来看一下具体的代码。

CAConfig (配置接口)

[java] view plain copy
  1. <span style="font-family:Comic Sans MS;font-size:12px;">package com.cacss.jsceu.context;  
  2.   
  3. /** 
  4.  * Created With IntelliJ IDEA. 
  5.  * 
  6.  * @author : lee 
  7.  * @group : sic-ca 
  8.  * @Date : 2014/12/30 
  9.  * @Comments : 配置接口 
  10.  * @Version : 1.0.0 
  11.  */  
  12. public interface CAConfig {  
  13.   
  14.     /** 
  15.      * C 
  16.      */  
  17.     String CA_C = "CN";  
  18.     /** 
  19.      * ST 
  20.      */  
  21.     String CA_ST = "BJ";  
  22.     /** 
  23.      * L 
  24.      */  
  25.     String CA_L = "BJ";  
  26.     /** 
  27.      */                                                                                                                                                                                                                                    
  28.     String CA_O = "SICCA";  
  29.       
  30.     /** 
  31.      * CA_ROOT_ISSUER 
  32.      */  
  33.     String CA_ROOT_ISSUER="C=CN,ST=BJ,L=BJ,O=SICCA,OU=SC,CN=SICCA";  
  34.     /** 
  35.      * CA_DEFAULT_SUBJECT 
  36.      */  
  37.     String CA_DEFAULT_SUBJECT="C=CN,ST=BJ,L=BJ,O=SICCA,OU=SC,CN=";  
  38.       
  39.     String CA_SHA="SHA256WithRSAEncryption";  
  40.   
  41. }</span>  


BaseCert (证书类

[java] view plain copy
  1. <span style="font-family:Comic Sans MS;font-size:12px;">package com.cacss.jsceu.test;  
  2.   
  3. import com.cacss.jsceu.context.CAConfig;  
  4. import com.cacss.jsceu.util.CertUtil;  
  5. import com.cacss.jsceu.util.DateUtil;  
  6. import org.bouncycastle.jce.provider.BouncyCastleProvider;  
  7. import org.bouncycastle.x509.X509V3CertificateGenerator;  
  8.   
  9. import javax.security.auth.x500.X500Principal;  
  10. import java.security.*;  
  11. import java.security.cert.X509Certificate;  
  12.   
  13.   
  14. /** 
  15.  * Created With IntelliJ IDEA. 
  16.  * 
  17.  * @author : lee 
  18.  * @group : sic-ca 
  19.  * @Date : 2014/12/30 
  20.  * @Comments : 证书类 
  21.  * @Version : 1.0.0 
  22.  */  
  23. @SuppressWarnings("all")  
  24. public class BaseCert {  
  25.     /** 
  26.      * BouncyCastleProvider 
  27.      */  
  28.     static {  
  29.         Security.addProvider(new BouncyCastleProvider());  
  30.     }  
  31.     /** 
  32.      *  
  33.      */  
  34.     protected static KeyPairGenerator kpg = null;  
  35.   
  36.     /** 
  37.  *  
  38.  */  
  39.     public BaseCert() {  
  40.         try {  
  41.             // 采用 RSA 非对称算法加密  
  42.             kpg = KeyPairGenerator.getInstance("RSA");  
  43.             // 初始化为 1023 位  
  44.             kpg.initialize(1024);  
  45.         } catch (NoSuchAlgorithmException e) {  
  46.             e.printStackTrace();  
  47.         }  
  48.   
  49.     }  
  50.   
  51.     /** 
  52.      * 生成 X509 证书 
  53.      * @param user 
  54.      * @return 
  55.      */  
  56.     public X509Certificate generateCert(String user) {  
  57.         X509Certificate cert = null;  
  58.         try {  
  59.             KeyPair keyPair = this.kpg.generateKeyPair();  
  60.             // 公钥  
  61.             PublicKey pubKey = keyPair.getPublic();  
  62.             // 私钥  
  63.             PrivateKey priKey = keyPair.getPrivate();  
  64.             X509V3CertificateGenerator certGen = new X509V3CertificateGenerator();  
  65.             // 设置序列号  
  66.             certGen.setSerialNumber(CertUtil.getNextSerialNumber());  
  67.             // 设置颁发者  
  68.             certGen.setIssuerDN(new X500Principal(CAConfig.CA_ROOT_ISSUER));  
  69.             // 设置有效期  
  70.             certGen.setNotBefore(DateUtil.getCurrDate());  
  71.             certGen.setNotAfter(DateUtil.getNextYear());  
  72.             // 设置使用者  
  73.             certGen.setSubjectDN(new X500Principal(CAConfig.CA_DEFAULT_SUBJECT + user));  
  74.             // 公钥  
  75.             certGen.setPublicKey(pubKey);  
  76.             // 签名算法  
  77.             certGen.setSignatureAlgorithm(CAConfig.CA_SHA);  
  78.             cert = certGen.generateX509Certificate(priKey, "BC");  
  79.         } catch (Exception e) {  
  80.             System.out.println(e.getClass() + e.getMessage());  
  81.         }  
  82.         return cert;  
  83.     }  
  84. }</span>  


GenerateCa (测试类)

[java] view plain copy
  1. <span style="font-family:Comic Sans MS;font-size:12px;">package com.cacss.jsceu.test;  
  2.   
  3. import java.io.FileNotFoundException;  
  4. import java.io.FileOutputStream;  
  5. import java.io.IOException;  
  6. import java.security.cert.CertificateEncodingException;  
  7. import java.security.cert.X509Certificate;  
  8.   
  9. /** 
  10.  * Created With IntelliJ IDEA. 
  11.  * 
  12.  * @author : lee 
  13.  * @group : sic-ca 
  14.  * @Date : 2014/12/30 
  15.  * @Comments : 测试证书类 
  16.  * @Version : 1.0.0 
  17.  */  
  18. public class GenerateCa {  
  19.     private static String certPath = "d:/lee.cer";  
  20.     public static void main(String[] args) {  
  21.         BaseCert baseCert = new BaseCert();  
  22.         X509Certificate cert = baseCert.generateCert("Lee");  
  23.         System.out.println(cert.toString());  
  24.   
  25.         // 导出为 cer 证书  
  26.         try {  
  27.             FileOutputStream fos = new FileOutputStream(certPath);  
  28.             fos.write(cert.getEncoded());  
  29.             fos.close();  
  30.         } catch (FileNotFoundException e) {  
  31.             e.printStackTrace();  
  32.         } catch (CertificateEncodingException e) {  
  33.             e.printStackTrace();  
  34.         } catch (IOException e) {  
  35.             e.printStackTrace();  
  36.         }  
  37.     }  
  38. }</span>  


效果图


下面是生成的证书,以及导出为 cer 格式的证书。

控制台打印
[plain] view plain copy
  1. <span style="font-family:Microsoft YaHei;font-size:12px;">Version: 3  
  2.      SerialNumber: 1419920991041  
  3.          IssuerDN: CN=SICCA,OU=SC,O=SICCA,L=BJ,ST=BJ,C=CN  
  4.        Start Date: Tue Dec 30 14:29:51 CST 2014  
  5.        Final Date: Wed Dec 30 14:29:51 CST 2015  
  6.         SubjectDN: CN=Lee,OU=SC,O=SICCA,L=BJ,ST=BJ,C=CN  
  7.        Public Key: RSA Public Key  
  8.         modulus: a9d5cc7de42c9afb468d7eb493bc69721443c0734edcb170ff13e062cc1b8d12e92edd347403d702288c5094ef2d0b2e811e0ee779a5e0a0cb7d5c75f30c5063eaa87aae7ba06bb3cf6ce6b0a5b0cd0cc2756255aff91fb09266b5dbbb6af491b5313947529d6a1fc30b9407ba1059bae909226c34e196b53c757a5826ffe147  
  9. public exponent: 10001  
  10.   
  11. Signature Algorithm: SHA256WITHRSA  
  12.         Signature: 8b8b725292147e9dbe8054ed99453386e1e6ba3d  
  13.                    8248b31a2dcb477900005207c039898dd2af4675  
  14.                    310471d3097f1aa3b6ff7e197f2ccf292dcd8ad1  
  15.                    ce6f19204a54a2dc8fe1fe118eaf81004ad06c7c  
  16.                    a04631f8a376272ddda5d4ae4980a1e2a3ee444e  
  17.                    a6b80a8532358f5e1a1b82c6a54ea2e36a02d3ea  
  18.                    8758c799df308d78</span>  

cer 证书






结束语


我这里使用的是第三方的组件 BC 包进行加密的,采用的是 RSA 的加密算法,证书中的密钥长度为 1024 位,当然,你也可以设置为 2048 位,根据你自己的需要选择即可。不过,需要说明的一点是,在使用公()钥加密的时候,需要加密的字符串的长度是有要求的,以 1024 位的密钥长度来说,那么需要加密的字符串的长度不能超过 117 个字符,计算公式:1024 / 8 - 11 = 117。所以,在加密长字符串的时候,就需要采用分片加密的方法了,这一点需要注意,当然,后续讲加密的文章中,我也会说明这一点。

0 0
原创粉丝点击