如何利用java來調用證書?(如何實現獲取證書公鑰以及客服信任號)
package ***.security;
import ***.io.*;
import ***.security.*;
import ***.security.cert.*;
import java.util.*;
import java.math.*;
import ***.security.x509.*;
* <p>Description: 該程序根據簽發者(CA)的證書信息(即CA的私鑰)來對被簽發者
* 的證書進行簽名,過程即是使用CA的證書和被簽證書來重構形成一個新的證書</p>
* @author abnerchai
* @version 1.0
public class SignCert {
public static void main(String[] args) throws Exception{
char[] storepass = "100200".toCharArray();
//存放CA證書和被簽證書的證書庫的訪問密碼
char[] cakeypass = "200100".toCharArray();//CA數字證書條目的訪問密碼
String alias = "missionCA";
//CA證書在證書庫中的別名,這個CA的證書用來簽名其它的證書
String name = "abnerCALib";//存放CA證書和被簽證書的證書庫的名字
String newLib = "SignedLib";
//新證書庫的名字,如果需要將簽名后的證書放入新庫,這是新庫的名字
char[] newLibPass = "100200".toCharArray();//設置新庫的訪問密碼
String cerFileName = "abnerCA.cer";//被簽證書的證書文件名
String aliasName = "abnerCA";//被簽證書在證書庫中的alias別名
char[] namePass = "200100".toCharArray();
//被簽證書的條目在證書庫的私鑰密碼
int n =3; //被簽證書的有效期,以年為單位,以當前時間開始計算
int sn = 200406001;
//序列號可自己定義,這里定義的意義為2004年6月簽發,是本年度CA簽發的第多少個以001計算,要求唯一
String afteraliasName = "abnerCA_Signed";
//簽名后新產生的被簽過名的證書在庫中的別名
char[] afterNewPass = "200100".toCharArray();
//簽名后新產生的被簽過名的證書在庫的條目的私鑰的密碼
//裝載證書庫
FileInputStream in = new FileInputStream(name);
KeyStore ks = KeyStore.getInstance("JKS");//JKS為證書庫的類型
ks.load(in,storepass);
//從證書庫中讀出簽發者(CA)的證書
***.security.cert.Certificate cl = ks.getCertificate(alias);
//讀出一個CA證書,這里的l是字母l不是數據字1
PrivateKey privateKey = (PrivateKey)ks.getKey(alias,cakeypass);
//根據別名和證書密碼讀出CA證書的私鑰
in.close();
//從證書庫中讀出的簽發者(CA)的證書中提取簽發者的信息
byte[] encodl = cl.getEncoded();//提取證書的編碼,這里是字母l不是數據字1
X509CertImpl cimpl = new X509CertImpl(encodl);
//這里是字母l不是數據字1,根據證書的編碼創建X509CertImpl類型的對象
//根據上面的對象獲得X509CertInfo類型的對象,該對象封裝了證書的全部內容。
X509CertInfo cinfo_first =
(X509CertInfo)cimpl.get(***.NAME+"."+***.INFO);
//然后獲得X500Name類型的簽發者信息
X500Name issuer = (X500Name)
cinfo_first.get(X509CertInfo.SUBJECT+"."+CertificateIssuerName.DN_NAME);
//獲取待簽發的證書,即獲取被簽發者的證書
//可從密鑰庫中獲取,也可從導出的證書文件中獲取,這里給出兩種方式 ////////////////////////////////////////////////////////////////////////
//方式一、采用從導出的cer文件中獲取 start
CertificateFactory cf = CertificateFactory.getInstance("X.509");
//X.509是使用最多的一種數字證書標準
FileInputStream in2 = new FileInputStream(cerFileName);//被簽證書文件
***.security.cert.Certificate c2 = cf.generateCertificate(in2);
//生成需要被簽的證書
in2.close();
byte[] encod2 = c2.getEncoded();
X509CertImpl cimp2 = new X509CertImpl(encod2);
//獲得被簽證書的詳細內容,然后根據這個證書生成新證書
X509CertInfo cinfo_second =
(X509CertInfo)cimp2.get(***.NAME+"."+***.INFO);
//end 方式一
//方式二、從證書庫中讀出被簽的證書 start
***.security.cert.Certificate c3 = ks.getCertificate(aliasName);
//從證書庫中讀出被簽證書,然后生成新的證書
byte[] encod3 = c3.getEncoded();
X509CertImpl cimp3 = new X509CertImpl(encod3);
X509CertInfo cinfo_second =
(X509CertInfo)cimp3.get(***.NAME+"."+***.INFO); ///////////////////////////////////////////////////////////////////////////
//end方式二
/////////////////////////////////////////////////////////////////////////// //設置新證書的有效期,使之為當前向后n年有效,新證書的
//截止日期不能超過CA證書的有效日期
Date beginDate = new Date();
Calendar cal = Calendar.getInstance();
cal.setTime(beginDate);
cal.add(cal.YEAR,n);
Date endDate = cal.getTime();
CertificateValidity cv = new CertificateValidity(beginDate,endDate);
cinfo_second.set(X509CertInfo.VALIDITY,cv);
//設置新證書的序列號
CertificateSerialNumber csn = new CertificateSerialNumber(sn);
cinfo_second.set(X509CertInfo.SERIAL_NUMBER,csn);
//設置新證書的簽發者
cinfo_second.set(X509CertInfo.ISSUER+"."+CertificateIssuerName.DN_NAME,issuer);
//新的簽發者是CA的證書中讀出來的
//設置新證書的算法,指定CA簽名該證書所使用的算法為md5WithRSA
AlgorithmId algorithm = new AlgorithmId(AlgorithmId.md5WithRSAEncryption_oid);
cinfo_second.set(***.NAME+"."+
CertificateAlgorithmId.ALGORITHM,algorithm);
//創建新的簽名后的證書
X509CertImpl newcert = new X509CertImpl(cinfo_second);
//簽名,使用CA證書的私鑰進行簽名,簽名使用的算法為MD5WithRSA
newcert.sign(privateKey,"MD5WithRSA");//這樣便得到了經過CA簽名后的證書
//把新證書存入證書庫
//把新生成的證書存入一個新的證書庫,也可以存入原證書庫,
//存入新證書庫,則新證書庫中不僅包含原證書庫中的所有條目,
//而且新增加了一個這次產生的條目。注意,這時,新產生的簽名后的證書只
//包括公鑰和主體信息及簽名信息,不包括私鑰信息。這里給出兩種方式。
//方式一:存入新密鑰庫
ks.setCertificateEntry(afteraliasName,newcert);
FileOutputStream out = new FileOutputStream(newLib);
//存入新庫signedLib,并設置新庫的庫訪問密碼
***.store(out,newLibPass);
out.close();
//end 方式一
//也可以采用另外一種方式,存入原證書庫中
//存入原庫中,即在原證書庫中增加一條證書,這個證書是原證書經過簽名后的證書
//這個新證書含有私鑰和私鑰密碼
//方式二,存入原密鑰庫
//先在原庫中讀出被簽證書的私鑰
PrivateKey prk = (PrivateKey)ks.getKey(aliasName,namePass);
***.security.cert.Certificate[] cchain = {newcert};
//存入原來的庫,第二個參數為原證書的私鑰,第三個參數為新證書的私鑰密碼,第三個參數為新證書
ks.setKeyEntry(afteraliasName,prk,afterNewPass,cchain); //用新密鑰替代原來的沒有簽名的證書的密碼
FileOutputStream out2 = new FileOutputStream(name);
***.store(out2,storepass);//存入原來的庫中,第二個參數為該庫的訪問密碼
//end 方式二