https://blog.csdn.net/zhushanzhi/article/details/77864516 版權聲明:本文為博主原創文章,未經博主允許不得轉載。 版權聲明:本文為博主原創文章,未經博主允許不得轉載。 [java] view plain copy package test; i ...
https://blog.csdn.net/zhushanzhi/article/details/77864516
版權聲明:本文為博主原創文章,未經博主允許不得轉載。
[java] view plain copy- package test;
- import java.io.ByteArrayOutputStream;
- import java.io.File;
- import java.io.FileInputStream;
- import java.io.FileNotFoundException;
- import java.io.FileOutputStream;
- import java.io.IOException;
- import java.io.InputStream;
- import java.io.OutputStream;
- import java.io.PrintStream;
- import java.security.Key;
- import java.security.KeyPair;
- import java.security.KeyPairGenerator;
- import java.security.KeyStore;
- import java.security.Principal;
- import java.security.PrivateKey;
- import java.security.PublicKey;
- import java.security.SecureRandom;
- import java.security.Signature;
- import java.security.cert.Certificate;
- import java.security.cert.CertificateException;
- import java.security.cert.CertificateFactory;
- import java.security.cert.CertificateFactorySpi;
- import java.security.cert.X509Certificate;
- import java.util.ArrayList;
- import java.util.Calendar;
- import java.util.Collection;
- import java.util.Date;
- import java.util.Enumeration;
- import java.util.HashMap;
- import java.util.List;
- import java.util.Map;
- import java.util.regex.Matcher;
- import java.util.regex.Pattern;
- import javax.crypto.KeyGenerator;
- import javax.crypto.SecretKey;
- import javax.crypto.spec.SecretKeySpec;
- import org.junit.Test;
- import sun.misc.BASE64Decoder;
- import sun.misc.BASE64Encoder;
- import sun.security.pkcs.ContentInfo;
- import sun.security.pkcs.PKCS10;
- import sun.security.pkcs.PKCS7;
- import sun.security.tools.KeyStoreUtil;
- import sun.security.x509.AlgorithmId;
- import sun.security.x509.CertificateAlgorithmId;
- import sun.security.x509.CertificateIssuerName;
- import sun.security.x509.CertificateSerialNumber;
- import sun.security.x509.CertificateSubjectName;
- import sun.security.x509.CertificateValidity;
- import sun.security.x509.CertificateVersion;
- import sun.security.x509.CertificateX509Key;
- import sun.security.x509.X500Name;
- import sun.security.x509.X500Signer;
- import sun.security.x509.X509CertImpl;
- import sun.security.x509.X509CertInfo;
- public class ReadKeyStoreTest {
- /**
- * 列出store中所有的私鑰和公鑰 以及簽名信息
- *
- * @param ks
- * @param storePass
- * @param priKeyPass
- * @throws Exception
- */
- private void listKeyAndCertificate(KeyStore ks, String storePass,
- String priKeyPass) throws Exception {
- System.out.println("size=" + ks.size());
- Enumeration<string> enum1 = ks.aliases();
- int i = 0;
- while (enum1.hasMoreElements()) {
- String alias = enum1.nextElement();
- System.out.println("第" + (++i) + "個");
- System.out.println("alias=" + alias);
- java.security.cert.Certificate c = ks.getCertificate(alias);// alias為條目的別名
- readX509Certificate((X509Certificate) c);
- readPriKey(ks, alias, priKeyPass);
- }
- }
- /**
- * 列出store中私鑰和cert chain信息
- *
- * @param ks
- * @param alias
- * @param pass
- * @throws Exception
- */
- private void readPriKey(KeyStore ks, String alias, String pass)
- throws Exception {
- Key key = ks.getKey(alias, pass.toCharArray());
- if (null == key) {
- System.out.println("no priviate key of " + alias);
- return;
- }
- System.out.println();
- System.out.println("algorithm=" + key.getAlgorithm());
- System.out.println("format=" + key.getFormat());
- System.out.println("toString=" + key);
- readCertChain(ks, alias);
- }
- /**
- * 列出store中 cert chain信息
- *
- * @param ks
- * @param alias
- * @throws Exception
- */
- private void readCertChain(KeyStore ks, String alias) throws Exception {
- Certificate[] certChain = ks.getCertificateChain(alias);
- System.out.println("chain of " + alias);
- if (null == certChain) {
- System.out.println("no chain");
- return;
- }
- int i = 0;
- for (Certificate c : certChain) {
- System.out.println("index " + (i++) + " in chain of " + alias);
- readX509Certificate((X509Certificate) c);
- }
- }
- /**
- * 列出x509Certificate的基本信息
- *
- * @param t
- */
- private void readX509Certificate(X509Certificate t) {
- System.out.println(t);
- System.out.println("輸出證書信息:\n" + t.toString());
- System.out.println("版本號:" + t.getVersion());
- System.out.println("序列號:" + t.getSerialNumber().toString(16));
- System.out.println("主體名:" + t.getSubjectDN());
- System.out.println("簽發者:" + t.getIssuerDN());
- System.out.println("有效期:" + t.getNotBefore());
- System.out.println("簽名演算法:" + t.getSigAlgName());
- byte[] sig = t.getSignature();// 簽名值
- PublicKey pk = t.getPublicKey();
- byte[] pkenc = pk.getEncoded();
- System.out.println("簽名 :");
- for (int i = 0; i < sig.length; i++)
- System.out.print(sig[i] + ",");
- System.out.println();
- System.out.println("公鑰: ");
- for (int i = 0; i < pkenc.length; i++)
- System.out.print(pkenc[i] + ",");
- System.out.println();
- }
- /**
- * 創建一個新的keystore
- *
- * @param storePass
- * @param storeType
- * PKCS12/JKS
- * @return
- * @throws Exception
- */
- private KeyStore createKeyStore(String storePass, String storeType)
- throws Exception {
- KeyStore ks = KeyStore.getInstance(storeType);
- ks.load(null, storePass.toCharArray());
- return ks;
- }
- /**
- * 載入一個已有的keyStore
- *
- * @param path
- * @param storePass
- * @param storeType
- * PKCS12/JKS
- * @return
- * @throws Exception
- */
- private KeyStore loadKeyStore(String path, String storePass,
- String storeType) throws Exception {
- FileInputStream in = new FileInputStream(path);
- KeyStore ks = KeyStore.getInstance(storeType);
- ks.load(in, storePass.toCharArray());
- in.close();
- return ks;
- }
- /**
- * 從文件載入一個證書
- *
- * @param path
- * @param certType
- * @return
- * @throws Exception
- */
- private Certificate loadCert(String path, String certType) throws Exception {
- CertificateFactory cf = CertificateFactory.getInstance(certType);
- FileInputStream in = new FileInputStream(path);
- Certificate c = cf.generateCertificate(in);
- in.close();
- return c;
- }
- /**
- * 生成一個由根證書簽名的store
- *
- * @param rootStore
- * @param rootAlias
- * @param rootKeyPass
- * @param subjectStr
- * @param storeType
- * @param storePass
- * @param alg
- * @param keySize
- * @param keyPass
- * @return
- * @throws Exception
- */
- public KeyStore generateSignedKeyStore(KeyStore rootStore,
- String rootAlias, String rootKeyPass, String subjectStr,
- String storeType, String storePass, String alias, String alg,
- int keySize, String keyPass) throws Exception {
- PrivateKey rootKey = null;
- X509CertImpl rootCert = null;
- X509CertInfo rootInfo = null;
- CertificateSubjectName rootsubject = null;
- // 簽發者
- X500Name issueX500Name = new X500Name(subjectStr);
- if (null != rootStore) {
- rootKey = (PrivateKey) rootStore.getKey(rootAlias,
- rootKeyPass.toCharArray());
- rootCert = (X509CertImpl) rootStore.getCertificate(rootAlias);
- rootInfo = (X509CertInfo) rootCert.get(X509CertImpl.NAME + "."
- + X509CertImpl.INFO);
- rootsubject = (CertificateSubjectName) rootInfo
- .get(X509CertInfo.SUBJECT);
- issueX500Name = (X500Name) rootsubject
- .get(CertificateIssuerName.DN_NAME);
- }
- // 簽發者
- CertificateIssuerName issuerName = new CertificateIssuerName(
- issueX500Name);
- // 被簽發者
- X500Name subjectX500Name = new X500Name(subjectStr);
- CertificateSubjectName subjectName = new CertificateSubjectName(
- subjectX500Name);
- // 有效期設置
- Calendar calendar = Calendar.getInstance();
- Date startDate = calendar.getTime();
- calendar.add(Calendar.DATE, 85);
- Date endDate = calendar.getTime();
- CertificateValidity certificateValidity = new CertificateValidity(
- startDate, endDate);
- // 序列號
- CertificateSerialNumber sn = new CertificateSerialNumber(
- (int) (startDate.getTime() / 1000L));
- // 版本
- CertificateVersion certVersion = new CertificateVersion(
- CertificateVersion.V3);
- // 演算法
- // TODO 獲取演算法的代碼有問題
- AlgorithmId algorithmId = new AlgorithmId(
- "RSA".equals(alg) ? AlgorithmId.sha1WithRSAEncryption_oid
- : AlgorithmId.sha1WithDSA_oid);
- // 密鑰對
- KeyPairGenerator keygen = KeyPairGenerator.getInstance(alg);
- keygen.initialize(keySize, new SecureRandom());
- KeyPair kp = keygen.genKeyPair();
- X509CertInfo certInfo = new X509CertInfo();
- certInfo.set("version", certVersion);
- certInfo.set("serialNumber", sn);
- // localX500Signer.getAlgorithmId();
- certInfo.set("algorithmID", new CertificateAlgorithmId(algorithmId));
- certInfo.set("key", new CertificateX509Key(kp.getPublic()));
- certInfo.set("validity", certificateValidity);
- certInfo.set("subject", subjectName);
- certInfo.set("issuer", issuerName);
- // 擴展信息
- // if (System.getProperty("sun.security.internal.keytool.skid") !=
- // null)
- // {
- // CertificateExtensions localCertificateExtensions = new
- // CertificateExtensions();
- // localCertificateExtensions.set("SubjectKeyIdentifier", new
- // SubjectKeyIdentifierExtension(new
- // KeyIdentifier(this.publicKey).getIdentifier()));
- // certInfo.set("extensions", localCertificateExtensions);
- // }
- X509CertImpl newcert = new X509CertImpl(certInfo);
- // TODO 這裡的簽名演算法可能有問題 貌似應該用rootcert的簽名演算法 待測試
- KeyStore ks = this.createKeyStore(storePass, storeType);
- Certificate[] certChain = null;
- // 如果rootStore為空 則生成自簽名證書
- if (null == rootStore) {
- newcert.sign(kp.getPrivate(), "SHA1WithRSA");
- certChain = new Certificate[] { newcert };
- } else {
- newcert.sign(rootKey, "SHA1WithRSA");
- certChain = new Certificate[] { newcert, rootCert };
- }
- // ks.setCertificateEntry("zrbin", newcert);
- ks.setKeyEntry(alias, kp.getPrivate(), keyPass.toCharArray(), certChain);
- return ks;
- }
- @Test
- public void testReadCer() throws Exception {
- String path = "d:\\test.cer";
- String certType = "X.509";
- CertificateFactory cf = CertificateFactory.getInstance(certType);
- FileInputStream in = new FileInputStream(path);
- Collection<certificate> cs = (Collection<certificate>) cf
- .generateCertificates(in);
- in.close();
- System.out.println("size=" + cs.size());
- for (Certificate c : cs) {
- readX509Certificate((X509Certificate) c);
- }
- }
- @Test
- public void testReadP12() throws Exception {
- String storePass = "123456";
- String keyPass = "123456";
- String path = "d:\\zrbin.p12";
- KeyStore ks = loadKeyStore(path, storePass, "PKCS12");
- listKeyAndCertificate(ks, storePass, keyPass);
- }
- @Test
- public void testReadKeyStore() throws Exception {
- String storePass = "123456";
- String keyPass = "123456";
- String path = "d:\\test.keystore";
- KeyStore ks = loadKeyStore(path, storePass, "JCEKS");
- listKeyAndCertificate(ks, storePass, keyPass);
- }
- @Test
- public void testExportCert() throws FileNotFoundException, Exception {
- String pass = "123456";
- FileInputStream in = new FileInputStream("d:\\zrbin.p12");
- boolean rfc = true;
- KeyStore ks = KeyStore.getInstance("PKCS12");
- ks.load(in, pass.toCharArray());
- Certificate cert = ks.getCertificate("zrbin");
- PrintStream out = new PrintStream("D:\\zrbin.cer");
- if (rfc) {
- BASE64Encoder encoder = new BASE64Encoder();
- out.println("-----BEGIN CERTIFICATE-----");
- encoder.encodeBuffer(cert.getEncoded(),
- out);
- out.println("-----END CERTIFICATE-----");
- } else {
- out.write(cert.getEncoded());
- }
- out.write(cert.getEncoded());
- }
- @Test
- public void testImportCert() throws Exception {
- CertificateFactory cf = CertificateFactory.getInstance("X.509");
- FileInputStream storeIn = new FileInputStream("d:\\server.keystore");
- FileInputStream in = new FileInputStream("d:\\zrbin.cer");
- FileInputStream rootin = new FileInputStream("d:\\root.cer");
- X509CertImpl cert = (X509CertImpl) cf.generateCertificate(in);
- X509CertImpl rootcert = (X509CertImpl) cf.generateCertificate(rootin);
- KeyStore ks = KeyStore.getInstance("JKS");
- ks.load(null, "123456".toCharArray());
- ks.deleteEntry("zrbin");
- // ks.setCertificateEntry("zrbin", cert);
- ks.setCertificateEntry("root", rootcert);
- in.close();
- FileOutputStream out = new FileOutputStream("d:\\server.keystore");
- ks.store(out, "123456".toCharArray());
- }
- @Test
- public void testImportSigenedCert() throws Exception {
- String alias = "test";
- CertificateFactory cf = CertificateFactory.getInstance("X.509");
- FileInputStream storeIn = new FileInputStream("d:\\test.keystore");
- KeyStore ks = KeyStore.getInstance("JKS");
- ks.load(storeIn, "123456".toCharArray());
- PrivateKey priKey = (PrivateKey) ks.getKey(alias,
- "123456".toCharArray());
- FileInputStream in = new FileInputStream("d:\\test.cer");
- Collection<certificate> certCollection = (Collection<certificate>) cf
- .generateCertificates(in);
- System.out.println(certCollection.size());
- if (certCollection.size() == 0) {
- System.out.println("沒有要導入的證書");
- return;
- }
- // 如果沒有對應的私鑰,直接導入certficateEntry
- if (null == priKey) {
- for (Certificate _cert : certCollection) {
- ks.setCertificateEntry(alias, _cert);
- break;
- }
- } else {
- Certificate importCert = null;
- for (Certificate cert : certCollection) {
- if (ks.getCertificate(alias).getPublicKey()
- .equals(cert.getPublicKey())) {
- importCert = cert;
- break;
- }
- }
- if (null == importCert) {
- System.out.println("錯誤:no replay cert");
- }
- certCollection.remove(importCert);
- if (X509CertImpl.isSelfSigned((X509Certificate) importCert, null)) {
- System.out.println("證書未被ca簽名,無需導入");
- } else {
- // 構建認證鏈
- List<certificate> certList = new ArrayList<certificate>(
- ks.size());
- Map<principal certificate=""> cerMap = new HashMap<principal certificate="">();
- Enumeration<string> aliasEnum = ks.aliases();
- // 把不包括當前回覆的都加到map里
- while (aliasEnum.hasMoreElements()) {
- String _alias = aliasEnum.nextElement();
- if (!_alias.equals(alias)) {
- X509CertImpl _cert = (X509CertImpl) ks
- .getCertificate(_alias);
- cerMap.put(_cert.getSubjectDN(), _cert);
- }
- }
- for (Certificate cert : certCollection) {
- cerMap.put(((X509Certificate) cert).getSubjectDN(), cert);
- }
- certList.add(importCert);
- Principal issuerName = ((X509Certificate) importCert)
- .getIssuerDN();
- while (cerMap.keySet().contains(issuerName)) {
- X509Certificate _rootCert = (X509Certificate) cerMap
- .remove(issuerName);
- if (null == _rootCert) {
- System.out.println(issuerName + "的根證書為空");
- return;
- }
- certList.add(_rootCert);
- issuerName = _rootCert.getIssuerDN();
- }
- X509CertImpl rootCert = (X509CertImpl) certList.get(certList
- .size() - 1);
- if (!X509CertImpl.isSelfSigned(rootCert, null)) {
- System.out.println("構建證書鏈錯誤,請先導入頒發者(" + issuerName
- + ")的CA證書");
- return;
- }
- Certificate[] certChain = certList
- .toArray(new Certificate[certList.size()]);
- ks.setKeyEntry(alias, priKey, "123456".toCharArray(), certChain);
- }
- }
- in.close();
- FileOutputStream out = new FileOutputStream("d:\\test.keystore");
- ks.store(out, "123456".toCharArray());
- &n