/**
*代碼實例 通過反編譯查看keytool的java code獲得的數字證書的內部生成方法
*推薦使用jdk1.5
**/
1。首先生成selfcert
CertAndKeyGen cak = new CertAndKeyGen("RSA","MD5WithRSA",null);
//參數分別為 公鑰算法 簽名算法 providername(因為不知道確切的 只好使用null 既使用默認的provider)
cak.generate(1024);
//生成一對key 參數為key的長度 對于rsa不能小于512
X500Name subject = new X500Name("CN=simic,o=shanghai");
//subject name
X509Certificate certificate = cak.getSelfCertificate(subject,10);
// 后一個long型參數代表從現在開始的有效期 單位為秒(如果不想從現在開始算 可以在后面改這個域)
BASE64Encoder base64 = new BASE64Encoder();
FileOutputStream fos = new FileOutputStream(new File("d:\\test.crt"));
base64.encodeBuffer(certificate.getEncoded(), fos);
//生成cert文件 base64加密 當然也可以不加密
2。生成非自簽的cert
首先按照1走一遍生成一個自簽證書
byte certbytes[] = certificate.getEncoded();
X509CertImpl x509certimpl = new X509CertImpl(certbytes);
X509CertInfo x509certinfo = (X509CertInfo)x509certimpl.get("x509.info");
X500Name issuer = new X500Name("CN=fatal,o=shanghai");
x509certinfo.set("issuer.dname",issuer);
//設置issuer域
Date bdate = new Date();
Date edate = new Date();
edate.setTime(bdate.getTime() + validity * 1000L * 24L * 60L * 60L);
//validity為有效時間長度 單位為秒
CertificateValidity certificatevalidity = new CertificateValidity(bdate, edate);
x509certinfo.set("validity", certificatevalidity);
//設置有效期域(包含開始時間和到期時間)域名等同與x509certinfo.VALIDITY
x509certinfo.set("serialNumber", new CertificateSerialNumber((int)(date.getTime() / 1000L)));
//設置序列號域
CertificateVersion cv = new CertificateVersion(CertificateVersion.V3);
x509certinfo.set(X509CertInfo.VERSION,cv);
//設置版本號 只有v1 ,v2,v3這幾個合法值
/**
*以上是證書的基本信息 如果要添加用戶擴展信息 則比較麻煩 首先要確定version必須是v3否則不行 然后按照以下步驟
**/
ObjectIdentifier oid = new ObjectIdentifier(new int[]{1,22});
//生成擴展域的id 是個int數組 第1位最大2 第2位最大39 最多可以幾位不明....
byte l = 0x11;//數據總長17位
byte f = 0x04;
String userData = "hohohohohahahahah";
byte[] bs = new byte[userData.length()+2];
bs[0] = f;
bs[1] = l;
for(int i=2;i<bs.length;i++)
{
bs[i] = (byte)userData.charAt(i-2);
}
Extension ext = new Extension(oid,true,bs);
// 生成一個extension對象 參數分別為 oid,是否關鍵擴展,byte[]型的內容值
//其中內容的格式比較怪異 第一位是flag 這里取4暫時沒出錯 估計用來說明數據的用處的 第2位是后面的實際數據的長度,然后就是數據
CertificateExtensions exts = new CertificateExtensions();
exts.set("aa",ext);
//如果有多個extension則都放入CertificateExtensions 類中,
x509certinfo.set(X509CertInfo.EXTENSIONS,exts);
//設置extensions域
X509CertImpl x509certimpl1 = new X509CertImpl(x509certinfo);
x509certimpl1.sign(cak1.getPrivateKey(), "MD5WithRSA");
//使用另一個證書的私鑰來簽名此證書 這里使用 md5散列 用rsa來加密
BASE64Encoder base64 = new BASE64Encoder();
FileOutputStream fos = new FileOutputStream(new File("d:\\test.crt"));
base64.encodeBuffer(x509certimpl1.getEncoded(), fos);
//生成文件
x509certimpl1.verify(cak.getPublicKey(),null);
//使用某個證書的公鑰驗證證書 如果驗證不通過 則會拋錯
很多地方沒仔細測過 可能有不正確之處還請多包涵