1. 程式人生 > >java實現安全證書相關操作

java實現安全證書相關操作

  1. package test;  
  2. import java.io.ByteArrayOutputStream;  
  3. import java.io.File;  
  4. import java.io.FileInputStream;  
  5. import java.io.FileNotFoundException;  
  6. import java.io.FileOutputStream;  
  7. import java.io.IOException;  
  8. import java.io.InputStream;  
  9. import java.io.OutputStream;  
  10. import java.io.PrintStream;  
  11. import java.security.Key;  
  12. import java.security.KeyPair;  
  13. import java.security.KeyPairGenerator;  
  14. import java.security.KeyStore;  
  15. import java.security.Principal;  
  16. import java.security.PrivateKey;  
  17. import java.security.PublicKey;  
  18. import java.security.SecureRandom;  
  19. import java.security.Signature;  
  20. import java.security.cert.Certificate;  
  21. import java.security.cert.CertificateException;  
  22. import java.security.cert.CertificateFactory;  
  23. import java.security.cert.CertificateFactorySpi;  
  24. import java.security.cert.X509Certificate;  
  25. import java.util.ArrayList;  
  26. import java.util.Calendar;  
  27. import java.util.Collection;  
  28. import java.util.Date;  
  29. import java.util.Enumeration;  
  30. import java.util.HashMap;  
  31. import java.util.List;  
  32. import java.util.Map;  
  33. import java.util.regex.Matcher;  
  34. import java.util.regex.Pattern;  
  35. import javax.crypto.KeyGenerator;  
  36. import javax.crypto.SecretKey;  
  37. import javax.crypto.spec.SecretKeySpec;  
  38. import org.junit.Test;  
  39. import sun.misc.BASE64Decoder;  
  40. import sun.misc.BASE64Encoder;  
  41. import sun.security.pkcs.ContentInfo;  
  42. import sun.security.pkcs.PKCS10;  
  43. import sun.security.pkcs.PKCS7;  
  44. import sun.security.tools.KeyStoreUtil;  
  45. import sun.security.x509.AlgorithmId;  
  46. import sun.security.x509.CertificateAlgorithmId;  
  47. import sun.security.x509.CertificateIssuerName;  
  48. import sun.security.x509.CertificateSerialNumber;  
  49. import sun.security.x509.CertificateSubjectName;  
  50. import sun.security.x509.CertificateValidity;  
  51. import sun.security.x509.CertificateVersion;  
  52. import sun.security.x509.CertificateX509Key;  
  53. import sun.security.x509.X500Name;  
  54. import sun.security.x509.X500Signer;  
  55. import sun.security.x509.X509CertImpl;  
  56. import sun.security.x509.X509CertInfo;  
  57. public class ReadKeyStoreTest {  
  58.     /** 
  59.      * 列出store中所有的私鑰和公鑰 以及簽名信息 
  60.      *  
  61.      * @param ks 
  62.      * @param storePass 
  63.      * @param priKeyPass 
  64.      * @throws Exception 
  65.      */  
  66.     private void listKeyAndCertificate(KeyStore ks, String storePass,  
  67.             String priKeyPass) throws Exception {  
  68.         System.out.println("size=" + ks.size());  
  69.         Enumeration<string> enum1 = ks.aliases();  
  70.         int i = 0;  
  71.         while (enum1.hasMoreElements()) {  
  72.             String alias = enum1.nextElement();  
  73.             System.out.println("第" + (++i) + "個");  
  74.             System.out.println("alias=" + alias);  
  75.             java.security.cert.Certificate c = ks.getCertificate(alias);// alias為條目的別名  
  76.             readX509Certificate((X509Certificate) c);  
  77.             readPriKey(ks, alias, priKeyPass);  
  78.         }  
  79.     }  
  80.     /** 
  81.      * 列出store中私鑰和cert chain資訊 
  82.      *  
  83.      * @param ks 
  84.      * @param alias 
  85.      * @param pass 
  86.      * @throws Exception 
  87.      */  
  88.     private void readPriKey(KeyStore ks, String alias, String pass)  
  89.             throws Exception {  
  90.         Key key = ks.getKey(alias, pass.toCharArray());  
  91.         if (null == key) {  
  92.             System.out.println("no priviate key of " + alias);  
  93.             return;  
  94.         }  
  95.         System.out.println();  
  96.         System.out.println("algorithm=" + key.getAlgorithm());  
  97.         System.out.println("format=" + key.getFormat());  
  98.         System.out.println("toString=" + key);  
  99.         readCertChain(ks, alias);  
  100.     }  
  101.     /** 
  102.      * 列出store中 cert chain資訊 
  103.      *  
  104.      * @param ks 
  105.      * @param alias 
  106.      * @throws Exception 
  107.      */  
  108.     private void readCertChain(KeyStore ks, String alias) throws Exception {  
  109.         Certificate[] certChain = ks.getCertificateChain(alias);  
  110.         System.out.println("chain of " + alias);  
  111.         if (null == certChain) {  
  112.             System.out.println("no chain");  
  113.             return;  
  114.         }  
  115.         int i = 0;  
  116.         for (Certificate c : certChain) {  
  117.             System.out.println("index " + (i++) + " in chain of " + alias);  
  118.             readX509Certificate((X509Certificate) c);  
  119.         }  
  120.     }  
  121.     /** 
  122.      * 列出x509Certificate的基本資訊 
  123.      *  
  124.      * @param t 
  125.      */  
  126.     private void readX509Certificate(X509Certificate t) {  
  127.         System.out.println(t);  
  128.         System.out.println("輸出證書資訊:\n" + t.toString());  
  129.         System.out.println("版本號:" + t.getVersion());  
  130.         System.out.println("序列號:" + t.getSerialNumber().toString(16));  
  131.         System.out.println("主體名:" + t.getSubjectDN());  
  132.         System.out.println("簽發者:" + t.getIssuerDN());  
  133.         System.out.println("有效期:" + t.getNotBefore());  
  134.         System.out.println("簽名演算法:" + t.getSigAlgName());  
  135.         byte[] sig = t.getSignature();// 簽名值  
  136.         PublicKey pk = t.getPublicKey();  
  137.         byte[] pkenc = pk.getEncoded();  
  138.         System.out.println("簽名 :");  
  139.         for (int i = 0; i < sig.length; i++)  
  140.             System.out.print(sig[i] + ",");  
  141.         System.out.println();  
  142.         System.out.println("公鑰: ");  
  143.         for (int i = 0; i < pkenc.length; i++)  
  144.             System.out.print(pkenc[i] + ",");  
  145.         System.out.println();  
  146.     }  
  147.     /** 
  148.      * 建立一個新的keystore 
  149.      *  
  150.      * @param storePass 
  151.      * @param storeType 
  152.      *            PKCS12/JKS 
  153.      * @return 
  154.      * @throws Exception 
  155.      */  
  156.     private KeyStore createKeyStore(String storePass, String storeType)  
  157.             throws Exception {  
  158.         KeyStore ks = KeyStore.getInstance(storeType);  
  159.         ks.load(null, storePass.toCharArray());  
  160.         return ks;  
  161.     }  
  162.     /** 
  163.      * 載入一個已有的keyStore 
  164.      *  
  165.      * @param path 
  166.      * @param storePass 
  167.      * @param storeType 
  168.      *            PKCS12/JKS 
  169.      * @return 
  170.      * @throws Exception 
  171.      */  
  172.     private KeyStore loadKeyStore(String path, String storePass,  
  173.             String storeType) throws Exception {  
  174.         FileInputStream in = new FileInputStream(path);  
  175.         KeyStore ks = KeyStore.getInstance(storeType);  
  176.         ks.load(in, storePass.toCharArray());  
  177.         in.close();  
  178.         return ks;  
  179.     }  
  180.     /** 
  181.      * 從檔案載入一個證書 
  182.      *  
  183.      * @param path 
  184.      * @param certType 
  185.      * @return 
  186.      * @throws Exception 
  187.      */  
  188.     private Certificate loadCert(String path, String certType) throws Exception {  
  189.         CertificateFactory cf = CertificateFactory.getInstance(certType);  
  190.         FileInputStream in = new FileInputStream(path);  
  191.         Certificate c = cf.generateCertificate(in);  
  192.         in.close();  
  193.         return c;  
  194.     }  
  195.     /** 
  196.      * 生成一個由根證書籤名的store 
  197.      *  
  198.      * @param rootStore 
  199.      * @param rootAlias 
  200.      * @param rootKeyPass 
  201.      * @param subjectStr 
  202.      * @param storeType 
  203.      * @param storePass 
  204.      * @param alg 
  205.      * @param keySize 
  206.      * @param keyPass 
  207.      * @return 
  208.      * @throws Exception 
  209.      */  
  210.     public KeyStore generateSignedKeyStore(KeyStore rootStore,  
  211.             String rootAlias, String rootKeyPass, String subjectStr,  
  212.             String storeType, String storePass, String alias, String alg,  
  213.             int keySize, String keyPass) throws Exception {  
  214.         PrivateKey rootKey = null;  
  215.         X509CertImpl rootCert = null;  
  216.         X509CertInfo rootInfo = null;  
  217.         CertificateSubjectName rootsubject = null;  
  218.         // 簽發者  
  219.         X500Name issueX500Name = new X500Name(subjectStr);  
  220.         if (null != rootStore) {  
  221.             rootKey = (PrivateKey) rootStore.getKey(rootAlias,  
  222.                     rootKeyPass.toCharArray());  
  223.             rootCert = (X509CertImpl) rootStore.getCertificate(rootAlias);  
  224.             rootInfo = (X509CertInfo) rootCert.get(X509CertImpl.NAME + "."  
  225.                     + X509CertImpl.INFO);  
  226.             rootsubject = (CertificateSubjectName) rootInfo  
  227.                     .get(X509CertInfo.SUBJECT);  
  228.             issueX500Name = (X500Name) rootsubject  
  229.                     .get(CertificateIssuerName.DN_NAME);  
  230.         }  
  231.         // 簽發者  
  232.         CertificateIssuerName issuerName = new CertificateIssuerName(  
  233.                 issueX500Name);  
  234.         // 被簽發者  
  235.         X500Name subjectX500Name = new X500Name(subjectStr);  
  236.         CertificateSubjectName subjectName = new CertificateSubjectName(  
  237.                 subjectX500Name);  
  238.         // 有效期設定  
  239.         Calendar calendar = Calendar.getInstance();  
  240.         Date startDate = calendar.getTime();  
  241.         calendar.add(Calendar.DATE, 85);  
  242.         Date endDate = calendar.getTime();  
  243.         CertificateValidity certificateValidity = new CertificateValidity(  
  244.                 startDate, endDate);  
  245.         // 序列號  
  246.         CertificateSerialNumber sn = new CertificateSerialNumber(  
  247.                 (int) (startDate.getTime() / 1000L));  
  248.         // 版本  
  249.         CertificateVersion certVersion = new CertificateVersion(  
  250.                 CertificateVersion.V3);  
  251.         // 演算法  
  252.         // TODO 獲取演算法的程式碼有問題  
  253.         AlgorithmId algorithmId = new AlgorithmId(  
  254.                 "RSA".equals(alg) ? AlgorithmId.sha1WithRSAEncryption_oid  
  255.                         : AlgorithmId.sha1WithDSA_oid);  
  256.         // 金鑰對  
  257.         KeyPairGenerator keygen = KeyPairGenerator.getInstance(alg);  
  258.         keygen.initialize(keySize, new SecureRandom());  
  259.         KeyPair kp = keygen.genKeyPair();  
  260.         X509CertInfo certInfo = new X509CertInfo();  
  261.         certInfo.set("version", certVersion);  
  262.         certInfo.set("serialNumber", sn);  
  263.         // localX500Signer.getAlgorithmId();  
  264.         certInfo.set("algorithmID", new CertificateAlgorithmId(algorithmId));  
  265.         certInfo.set("key", new CertificateX509Key(kp.getPublic()));  
  266.         certInfo.set("validity", certificateValidity);  
  267.         certInfo.set("subject", subjectName);  
  268.         certInfo.set("issuer", issuerName);  
  269.         // 擴充套件資訊  
  270.         // if (System.getProperty("sun.security.internal.keytool.skid") !=  
  271.         // null)  
  272.         // {  
  273.         // CertificateExtensions localCertificateExtensions = new  
  274.         // CertificateExtensions();  
  275.         // localCertificateExtensions.set("SubjectKeyIdentifier", new  
  276.         // SubjectKeyIdentifierExtension(new  
  277.         // KeyIdentifier(this.publicKey).getIdentifier()));  
  278.         // certInfo.set("extensions", localCertificateExtensions);  
  279.         // }  
  280.         X509CertImpl newcert = new X509CertImpl(certInfo);  
  281.         // TODO 這裡的簽名演算法可能有問題 貌似應該用rootcert的簽名演算法 待測試  
  282.         KeyStore ks = this.createKeyStore(storePass, storeType);  
  283.         Certificate[] certChain = null;  
  284.         // 如果rootStore為空 則生成自簽名證書  
  285.         if (null == rootStore) {  
  286.             newcert.sign(kp.getPrivate(), "SHA1WithRSA");  
  287.             certChain = new Certificate[] { newcert };  
  288.         } else {  
  289.             newcert.sign(rootKey, "SHA1WithRSA");  
  290.             certChain = new Certificate[] { newcert, rootCert };  
  291.         }  
  292.         // ks.setCertificateEntry("zrbin", newcert);  
  293.         ks.setKeyEntry(alias, kp.getPrivate(), keyPass.toCharArray(), certChain);  
  294.         return ks;  
  295.     }  
  296.     @Test  
  297.     public void testReadCer() throws Exception {  
  298.         String path = "d:\\test.cer";  
  299.         String certType = "X.509";  
  300.         CertificateFactory cf = CertificateFactory.getInstance(certType);  
  301.         FileInputStream in = new FileInputStream(path);  
  302.         Collection<certificate> cs = (Collection<certificate>) cf  
  303.                 .generateCertificates(in);  
  304.         in.close();  
  305.         System.out.println("size=" + cs.size());  
  306.         for (Certificate c : cs) {  
  307.             readX509Certificate((X509Certificate) c);  
  308.         }  
  309.     }  
  310.     @Test  
  311.     public void testReadP12() throws Exception {  
  312.         String storePass = "123456";  
  313.         String keyPass = "123456";  
  314.         String path = "d:\\zrbin.p12";  
  315.         KeyStore ks = loadKeyStore(path, storePass, "PKCS12");  
  316.         listKeyAndCertificate(ks, storePass, keyPass);  
  317.     }  
  318.     @Test  
  319.     public void testReadKeyStore() throws Exception {  
  320.         String storePass = "123456";  
  321.         String keyPass = "123456";  
  322.         String path = "d:\\test.keystore";  
  323.         KeyStore ks = loadKeyStore(path, storePass, "JCEKS");  
  324.         listKeyAndCertificate(ks, storePass, keyPass);  
  325.     }  
  326.     @Test  
  327.     public void testExportCert() throws FileNotFoundException, Exception {  
  328.         String pass = "123456";  
  329.         FileInputStream in = new FileInputStream("d:\\zrbin.p12");  
  330.         boolean rfc = true;  
  331.         KeyStore ks = KeyStore.getInstance("PKCS12");  
  332.         ks.load(in, pass.toCharArray());  
  333.         Certificate cert = ks.getCertificate("zrbin");  
  334.         PrintStream out = new PrintStream("D:\\zrbin.cer");  
  335.         if (rfc) {  
  336.             BASE64Encoder encoder = new BASE64Encoder();  
  337.             out.println("-----BEGIN CERTIFICATE-----");  
  338.             encoder.encodeBuffer(cert.getEncoded(),  
  339.                     out);  
  340.             out.println("-----END CERTIFICATE-----");  
  341.         } else {  
  342.             out.write(cert.getEncoded());  
  343.         }  
  344.         out.write(cert.getEncoded());  
  345.     }  
  346.     @Test  
  347.     public void testImportCert() throws Exception {  
  348.         CertificateFactory cf = CertificateFactory.getInstance("X.509");  
  349.         FileInputStream storeIn = new FileInputStream("d:\\server.keystore");  
  350.         FileInputStream in = new FileInputStream("d:\\zrbin.cer");  
  351.         FileInputStream rootin = new FileInputStream("d:\\root.cer");  
  352.         X509CertImpl cert = (X509CertImpl) cf.generateCertificate(in);  
  353.         X509CertImpl rootcert = (X509CertImpl) cf.generateCertificate(rootin);  
  354.         KeyStore ks = KeyStore.getInstance("JKS");  
  355.         ks.load(null, "123456".toCharArray());  
  356.         ks.deleteEntry("zrbin");  
  357.         // ks.setCertificateEntry("zrbin", cert);  
  358.         ks.setCertificateEntry("root", rootcert);  
  359.         in.close();  
  360.         FileOutputStream out = new FileOutputStream("d:\\server.keystore");  
  361.         ks.store(out, "123456".toCharArray());  
  362.     }  
  363.     @Test  
  364.     public void testImportSigenedCert() throws Exception {  
  365.         String alias = "test";  
  366.         CertificateFactory cf = CertificateFactory.getInstance("X.509");  
  367.         FileInputStream storeIn = new FileInputStream("d:\\test.keystore");  
  368.         KeyStore ks = KeyStore.getInstance("JKS");  
  369.         ks.load(storeIn, "123456".toCharArray());  
  370.         PrivateKey priKey = (PrivateKey) ks.getKey(alias,  
  371.                 "123456".toCharArray());  
  372.         FileInputStream in = new FileInputStream("d:\\test.cer");  
  373.         Collection<certificate> certCollection = (Collection<certificate>) cf  
  374.                 .generateCertificates(in);  
  375.         System.out.println(certCollection.size());  
  376.         if (certCollection.size() == 0) {  
  377.             System.out.println("沒有要匯入的證書");  
  378.             return;  
  379.         }  
  380.         // 如果沒有對應的私鑰,直接匯入certficateEntry  
  381.         if (null == priKey) {  
  382.             for (Certificate _cert : certCollection) {  
  383.                 ks.setCertificateEntry(alias, _cert);  
  384.                 break;  
  385.             }  
  386.         } else {  
  387.             Certificate importCert = null;  
  388.             for (Certificate cert : certCollection) {  
  389.                 if (ks.getCertificate(alias).getPublicKey()  
  390.                         .equals(cert.getPublicKey())) {  
  391.                     importCert = cert;  
  392.                     break;  
  393.                 }  
  394.             }  
  395.             if (null == importCert) {  
  396.                 System.out.println("錯誤:no replay cert");  
  397.             }  
  398.             certCollection.remove(importCert);  
  399.             if (X509CertImpl.isSelfSigned((X509Certificate) importCert, null)) {  
  400.                 System.out.println("證書未被ca簽名,無需匯入");  
  401.             } else {  
  402.                 // 構建認證鏈  
  403.                 List<certificate> certList = new ArrayList<certificate>(  
  404.                         ks.size());  
  405.                 Map<principal certificate=""> cerMap = new HashMap<principal certificate="">();  
  406.                 Enumeration<string> aliasEnum = ks.aliases();  
  407.                 // 把不包括當前回覆的都加到map裡  
  408.                 while (aliasEnum.hasMoreElements()) {  
  409.                     String _alias = aliasEnum.nextElement();  
  410.                     if (!_alias.equals(alias)) {  
  411.                         X509CertImpl _cert = (X509CertImpl) ks  
  412.                                 .getCertificate(_alias);  
  413.                         cerMap.put(_cert.getSubjectDN(), _cert);  
  414.                     }  
  415.                 }  
  416.                 for (Certificate cert : certCollection) {  
  417.                     cerMap.put(((X509Certificate) cert).getSubjectDN(), cert);  
  418.                 }  
  419.                 certList.add(importCert);  
  420.                 Principal issuerName = ((X509Certificate) importCert)  
  421.                         .getIssuerDN();  
  422.                 while (cerMap.keySet().contains(issuerName)) {  
  423.                     X509Certificate _rootCert = (X509Certificate) cerMap  
  424.                             .remove(issuerName);  
  425.                     if (null == _rootCert) {  
  426.                         System.out.println(issuerName + "的根證書為空");  
  427.                         return;  
  428.                     }  
  429.                     certList.add(_rootCert);  
  430.                     issuerName = _rootCert.getIssuerDN();  
  431.                 }  
  432.                 X509CertImpl rootCert = (X509CertImpl) certList.get(certList  
  433.                         .size() - 1);  
  434.                 if (!X509CertImpl.isSelfSigned(rootCert, null)) {  
  435.                     System.out.println("構建證書鏈錯誤,請先匯入頒發者(" + issuerName  
  436.                             + ")的CA證書");  
  437.                     return;  
  438.                 }  
  439.                 Certificate[] certChain = certList  
  440.                         .toArray(new Certificate[certList.size()]);  
  441.                 ks.setKeyEntry(alias, priKey, "123456".toCharArray(), certChain);  
  442.             }  
  443.         }  
  444.         in.close();  
  445.         FileOutputStream out = new FileOutputStream("d:\\test.keystore");  
  446.         ks.store(out, "123456".toCharArray());  
  447.         out.close();  
  448.     }  
  449.     @Test  
  450.     public void testGenerateKeyStore() throws Exception {  
  451.         KeyPairGenerator kg = KeyPairGenerator.getInstance("RSA");  
  452.         KeyPair kp = kg.genKeyPair();  
  453.         System.out.println(KeyStoreUtil.niceStoreTypeName("PKCS12"));  
  454.         System.out.println(kp.getPrivate());  
  455.         System.out.println(kp.getPublic());  
  456.         KeyStore ks = KeyStore.getInstance("JKS");  
  457.     }  
  458.     @Test  
  459.     public void testX500Name() throws IOException, CertificateException {  
  460.         // for(byte i=48;i<=57;i++){  
  461.         // System.out.println((char)i);  
  462.         // }  
  463.         // RFC 1779 (CN, L, ST, O, OU, C, STREET)  
  464.         // RFC 2253 (CN/name, L/location, ST/station, O/org, OU/orgunit,  
  465.         // C/country, STREET, DC, UID)  
  466.         X500Name subjectName = new X500Name(  
  467.                 "CN=www.jiangtech.com,L=ZuChongZhi road,ST=Shang Hai,O=Jiangdatech,OU=ENTERPRISE APP,C=China,STREET=ZuChongZhi Road");  
  468.         X500Name subjectName1 = new X500Name(  
  469.                 "CN=www.jiangtech.com,L=ZuChongZhi road,ST=Shang Hai,O=Jiangdatech,OU=ENTERPRISE APP,C=China,STREET=ZuChongZhi Road");  
  470.         // X509CertInfo certInfo = new X509CertInfo();  
  471.         // certInfo.set(X509CertInfo.SUBJECT, new CertificateSubjectName(  
  472.         // subjectName));  
  473.         System.out.println(subjectName.hashCode());  
  474.         System.out.println(subjectName1.hashCode());  
  475.     }  
  476.     /** 
  477.      * 證書驗證 
  478.      *  
  479.      * @throws Exception 
  480.      */  
  481.     @Test  
  482.     public void testValidate() throws Exception {  
  483.         KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");  
  484.         // kpg.initialize()  
  485.         KeyPair kp = kpg.genKeyPair();  
  486.         KeyStore rootStore = this.loadKeyStore("d:/root.keystore", "123456",  
  487.                 "JKS");  
  488.         PrivateKey rootKey = (PrivateKey) rootStore.getKey("jdcert",  
  489.                 "123456".toCharArray());  
  490.         KeyStore store1 = this.loadKeyStore("d:/jd_signed.keystore", "123456",  
  491.                 "JKS");  
  492.         X509CertImpl rootCert = (X509CertImpl) rootStore  
  493.                 .getCertificate("jdcert");  
  494.         X509CertInfo rootInfo = (X509CertInfo) rootCert.get(X509CertImpl.NAME  
  495.                 + "." + X509CertImpl.INFO);  
  496.         CertificateSubjectName rootsubject = (CertificateSubjectName) rootInfo  
  497.                 .get(X509CertInfo.SUBJECT);  
  498.         Certificate[] chain = rootStore.getCertificateChain("jdcert");  
  499.         rootCert.verify(kp.getPublic());  
  500.     }  
  501.     /** 
  502.      * 測試簽發證書 
  503.      */  
  504.     @Test  
  505.     public void testGenerateSignedKeyStore() {  
  506.         try {  
  507.             KeyStore rootStore = this.loadKeyStore("d:/root.keystore",  
  508.                     "123456", "JKS");  
  509.             String rootAlias = "test";  
  510.             String subjectStr = "[email protected],L=PU Dong,ST=Shang Hai,O=Jiangdatech,OU=ENTERPRISE APP,C=China,STREET=ZuChongZhi Road";  
  511.             String alg = "RSA";  
  512.             String storeType = "JKS";  
  513.             int keySize = 1024;  
  514.             String keyPass = "123456";  
  515.             String rootKeyPass = "123456";  
  516.             String storePass = "123456";  
  517.             String alias = "test";  
  518.             KeyStore ks = this.generateSignedKeyStore(null, rootAlias,  
  519.                     rootKeyPass, subjectStr, storeType, storePass, alias, alg,  
  520.                     keySize, keyPass);  
  521.             OutputStream out = new FileOutputStream(  
  522.                     new File("d:/test.keystore"));  
  523.             ks.store(out, "123456".toCharArray());  
  524.         } catch (Exception e) {  
  525.             e.printStackTrace();  
  526.         }  
  527.     }  
  528.     /** 
  529.      * 測試簽發證書 
  530.      */  
  531.     @Test  
  532.     public void testGenerateSecKeyStore() {  
  533.         try {  
  534.             String rootAlias = "test";  
  535.             String subjectStr = "[email protected],L=PU Dong,ST=Shang Hai,O=Jiangdatech,OU=ENTERPRISE APP,C=China,STREET=ZuChongZhi Road";  
  536.             String alg = "DES";  
  537.             String storeType = "JKS";  
  538.             int keySize = 1024;  
  539.             String keyPass = "123456";  
  540.             String rootKeyPass = "123456";  
  541.             String storePass = "123456";  
  542.             String alias = "test";  
  543.             KeyStore ks = this.createKeyStore("123456", "JCEKS");  
  544.             KeyGenerator keygen = KeyGenerator.getInstance("DES");  
  545.             SecretKey secKey = keygen.generateKey();  
  546.             ks.setKeyEntry(alias, secKey, "123456".toCharArray(),null);  
  547.             OutputStream out = new FileOutputStream(  
  548.                     new File("d:/test.keystore"));  
  549.             ks.store(out, "123456".toCharArray());  
  550.         } catch (Exception e) {  
  551.             e.printStackTrace();  
  552.         }  
  553.     }  
  554.     @Test  
  555.     /** 
  556.      * 關於p7b的操作 未實現 
  557.      */  
  558.     public void testGeneratePKCS7KeyStore() {  
  559.         try {  
  560.             /*ContentInfo info = new ContentInfo(arg0); 
  561.             //PKCS7 pkcs7 = new PKCS7() 
  562.             String rootAlias = "test"; 
  563.             String subjectStr = "[email protected],L=PU Dong,ST=Shang Hai,O=Jiangdatech,OU=ENTERPRISE APP,C=China,STREET=ZuChongZhi Road"; 
  564.             String alg = "DES"; 
  565.             String storeType = "JKS"; 
  566.             int keySize = 1024; 
  567.             String keyPass = "123456"; 
  568.             String rootKeyPass = "123456"; 
  569.             String storePass = "123456"; 
  570.             String alias = "test"; 
  571.             KeyStore ks = this.createKeyStore("123456", "PKCS7"); 
  572.             KeyGenerator keygen = KeyGenerator.getInstance("RSA"); 
  573.             //SecretKey secKey = keygen.generateKey(); 
  574.             //ks.setKeyEntry(alias, secKey, "123456".toCharArray(),null); 
  575.             OutputStream out = new FileOutputStream( 
  576.                     new File("d:/test.keystore")); 
  577.             ks.store(out, "123456".toCharArray());*/  
  578.         } catch (Exception e) {  
  579.             e.printStackTrace();  
  580.         }  
  581.     }  
  582.     @Test  
  583.     public void testReadJCEKS() throws Exception{  
  584.         KeyStore ks = this.loadKeyStore("D:/test.keystore","123456", "JCEKS");  
  585.         Enumeration<string> aliasEnum = ks.aliases();  
  586.         while(aliasEnum.hasMoreElements()){  
  587.             String alias = aliasEnum.nextElement();  
  588.             SecretKeySpec secKey = (SecretKeySpec) ks.getKey(alias, "123456".toCharArray());  
  589.             System.out.println(ks.getCertificate(alias));  
  590.             //System.out.println(ks.);  
  591.             System.out.println(secKey.getClass());  
  592.             System.out.println(secKey.getFormat());  
  593.             System.out.println(secKey.getEncoded());  
  594.         }  
  595.     }  
  596.     public PKCS10 readCsr() throws Exception {  
  597.         File f = new File("D:/test.csr");  
  598.         InputStream in = new FileInputStream(f);  
  599.         ByteArrayOutputStream out = new ByteArrayOutputStream(1024);  
  600.         byte[] bytes = new byte[(int) f.length()];  
  601.         in.read(bytes);  
  602.         String base64String = new String(bytes, "ISO-8859-1");  
  603.         System.out.println(base64String);  
  604.         Pattern p = Pattern  
  605.                 .compile("-----BEGIN NEW CERTIFICATE REQUEST-----([\\s\\S]*?)-----END NEW CERTIFICATE REQUEST-----([\\s\\S]*)");  
  606.         BASE64Decoder decoder = new BASE64Decoder();  
  607.         Matcher m = p.matcher(base64String);  
  608.         if (m.find()) {  
  609.             String s = m.group(1);  
  610.             System.out.println(s.trim());  
  611.             byte[] bArray = decoder.decodeBuffer(s);  
  612.             PKCS10 csr = new PKCS10(bArray);  
  613.             System.out.println(csr);  
  614.             return csr;  
  615.         }  
  616.         throw new Exception("檔案錯誤 ,無法讀取csr");  
  617.     }  
  618.     @Test  
  619.     public void testReadCsr() throws Exception {  
  620.         PKCS10 csr = readCsr();  
  621.     }  
  622.     @Test  
  623.     public void createCsr() throws Exception {  
  624.         String storePass = "123456";  
  625.         String alias = "test";  
  626.         String alg = null;  
  627.         KeyStore ks = this.loadKeyStore("d:/test.keystore", storePass, "JKS");  
  628.         Certificate cert = ks.getCertificate(alias);  
  629.         PrivateKey priKey = (PrivateKey) ks.getKey(alias,  
  630.                 "123456".toCharArray());  
  631.         PublicKey pubKey = cert.getPublicKey();  
  632.         PKCS10 csr = new PKCS10(pubKey);  
  633.         String signAlg = null;  
  634.         if (alg == null) {  
  635.             alg = priKey.getAlgorithm();  
  636.             if (("DSA".equalsIgnoreCase(alg)) || ("DSS".equalsIgnoreCase(alg)))  
  637.                 signAlg = "SHA1WithDSA";  
  638.             else if ("RSA".equalsIgnoreCase((String) alg))  
  639.                 signAlg = "SHA1WithRSA";  
  640.             else  
  641.                 throw new Exception("Cannot derive signature algorithm");  
  642.         }  
  643.         Signature signature = Signature.getInstance(signAlg);  
  644.         signature.initSign(priKey);  
  645.         X500Name x500Name = new X500Name(((X509Certificate) cert)  
  646.                 .getSubjectDN().toString());  
  647.         X500Signer x500Signer = new X500Signer(signature, x500Name);  
  648.         ((PKCS10) csr).encodeAndSign(x500Signer);  
  649.         File f = new File("D:/test.csr");  
  650.         if (f.exists()) {  
  651.             f.delete();  
  652.         }  
  653.         ((PKCS10) csr).print(new PrintStream(new File("D:/test.csr")));  
  654.     }  
  655.     /** 
  656.      * 簽名 
  657.      *  
  658.      * @throws Exception 
  659.      */  
  660.     @Test  
  661.     public void testSignature() throws Exception {  
  662.         KeyStore rootStore = this.loadKeyStore("d:/root.keystore", "123456",  
  663.                 "JKS");  
  664.         PrivateKey rootKey = (PrivateKey) rootStore.getKey("root",  
  665.                 "123456".toCharArray());  
  666.         X509CertImpl rootX509Cert = (X509CertImpl) rootStore  
  667.                 .getCertificate("root");  
  668.         X500Name issuerX500Name = (X500Name) rootX509Cert.get(X509CertImpl.NAME  
  669.                 + "." + X509CertImpl.INFO + "." + X509CertInfo.SUBJECT + "."  
  670.                 + CertificateSubjectName.DN_NAME);  
  671.         // 有效期設定  
  672.         Calendar calendar = Calendar.getInstance();  
  673.         Date startDate = calendar.getTime();  
  674.         calendar.add(Calendar.DATE, 85);  
  675.         Date endDate = calendar.getTime();  
  676.         CertificateValidity certificateValidity = new CertificateValidity(  
  677.                 startDate, endDate);  
  678.         // 序列號  
  679.         CertificateSerialNumber sn = new CertificateSerialNumber(  
  680.                 (int) (startDate.getTime() / 1000L));  
  681.         PKCS10 csr = this.readCsr();  
  682.         PublicKey pubKey = csr.getSubjectPublicKeyInfo();  
  683.         X500Name subjectX500Name = csr.getSubjectName();  
  684.         // TODO 未實現  
  685.         Signature signature = Signature.getInstance("Sha1WithRSA");  
  686.         X500Signer signer = new X500Signer(signature, subjectX500Name);  
  687.         AlgorithmId algorithmId = signer.getAlgorithmId();  
  688.         X509CertInfo info = new X509CertInfo();  
  689.         info.set(X509CertInfo.ALGORITHM_ID, new CertificateAlgorithmId(  
  690.                 algorithmId));  
  691.         info.set(X509CertInfo.SUBJECT, new CertificateSubjectName(  
  692.                 subjectX500Name));  
  693.         info.set(X509CertInfo.ISSUER, new CertificateIssuerName(issuerX500Name));  
  694.         info.set(X509CertInfo.KEY, new CertificateX509Key(pubKey));  
  695.         info.set(X509CertInfo.VERSION, new CertificateVersion(  
  696.                 CertificateVersion.V3));  
  697.         info.set(X509CertInfo.VALIDITY, certificateValidity);  
  698.         info.set(X509CertInfo.SERIAL_NUMBER, sn);  
  699.         X509CertImpl newCert = new X509CertImpl(info);  
  700.         newCert.sign(rootKey, "SHA1WithRSA");  
  701.         OutputStream out = new FileOutputStream("d:/test.cer");  
  702.         out.write(newCert.getEncoded());  
  703.         out.write(rootX509Cert.getEncoded());  
  704.         out.close();  
  705.     }  
  706. }