用戶首先產生自己的密鑰對,並將公共密鑰及部分個人信息傳送給CA(通過P10請求)
CertAndKeyGen gen = new CertAndKeyGen("RSA", "SHA1WithRSA");
gen.generate(1024);//生成1024位密鑰
PKCS10CertificationRequestBuilder p10Builder = new JcaPKCS10CertificationRequestBuilder(
new X500Principal("CN = " + name), gen.getPublicKey());// CN和公鑰
JcaContentSignerBuilder csBuilder = new JcaContentSignerBuilder("SHA256withRSA");// 簽名算法
ContentSigner signer = null;
signer = csBuilder.build(gen.getPrivateKey());
PKCS10CertificationRequest csr = p10Builder.build(signer);// PKCS10的請求
return csr;//返回PKCS10的請求
CA接受請求並生成證書
CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
X509Certificate cacert = (X509Certificate) certFactory.generateCertificate(new FileInputStream(certPath));
//一大堆參數 ,填充到生成器里
AlgorithmIdentifier sigAlgId = new DefaultSignatureAlgorithmIdentifierFinder().find("SHA1withRSA");
AlgorithmIdentifier digAlgId = new DefaultDigestAlgorithmIdentifierFinder().find(sigAlgId);
org.bouncycastle.asn1.x500.X500Name issuer = new org.bouncycastle.asn1.x500.X500Name(
cacert.getSubjectX500Principal().getName());
BigInteger serial = new BigInteger(32, new SecureRandom());
Date from = new Date();
Date to = new Date(System.currentTimeMillis() + (365 * 80 * 86400000L));
X509v3CertificateBuilder certgen = new X509v3CertificateBuilder(issuer, serial, from, to, csr.getSubject(),
csr.getSubjectPublicKeyInfo())
Key privateKey = productPrivateKey();
// CA端進行簽名, 才有具有法律效力
ContentSigner signer = new BcRSAContentSignerBuilder(sigAlgId, digAlgId)
.build(PrivateKeyFactory.createKey(privateKey.getEncoded()));
// 生成BC結構的證書
Security.addProvider(new BouncyCastleProvider());
X509Certificate resultBc = new JcaX509CertificateConverter().setProvider("BC").getCertificate(certgen.build(signer));
return resultBc;//返回證書
CSR:證書簽發請求(Certificate Signing Request),
-
CSR也叫做認證申請,是一個發送到CA的請求認證信息。 有兩種格式,應用最廣泛的是由PKCS#10定義的,另一個用的少的是由SPKAC定義的,主要應用於網景瀏覽器。
-
在PKCS#10定義中,CSR有兩種編碼格式:二進制(ASN.1或DER (Distinguished Encoding Rules))和文本格式(the text or PEM (Privacy Enhanced Mail)formatted CSR is the binary CSR after it has been Base-64 encoded to create a text version of the CSR.)
-
CSR文件生成步驟如下:
- 根據Version、Distinguished Name、Public Key、Attributes生成請求證書;
- 用Private Key加密證書請求信息;
- 根據請求信息、簽名算法和簽名生成CSR文件;
-
CSR文件包含的信息描述如下
CertificationRequest ::= SEQUENCE {
certificationRequestInfo CertificationRequestInfo,//證書信息
signatureAlgorithm AlgorithmIdentifier{{ SignatureAlgorithms }},//簽名算法
signature BIT STRING //簽名
}//另外還可能有可選的字段,如postal address和Email address,這兩個字段可以應用於證書的撤銷。
注意:私鑰不包含在CSR文件中,但是應用於數字簽名。
簽名分兩步
-
將certificateRequestInfo 進行DER編碼,產生八位字節字符串;
-
將步驟一的結果用請求者的私鑰在指定的簽名算法下,產生簽名;
-
請求信息定義如下
CertificationRequestInfo ::= SEQUENCE {
version INTEGER { v1(0) } (v1,...),
subject Name, //證書主體的專有名稱
subjectPKInfo SubjectPublicKeyInfo{{ PKInfoAlgorithms }},
attributes [0] Attributes{{ CRIAttributes }}
}
-
subjectPublicKeyInfo 包含被認證的公鑰
-
attributes 關於認證主提其他信息屬性集合
SubjectPublicKeyInfo { ALGORITHM : IOSet} ::= SEQUENCE {
algorithm AlgorithmIdentifier {{IOSet}},
subjectPublicKey BIT STRING
}
PKInfoAlgorithms ALGORITHM ::= {
... -- add any locally defined algorithms here -- }
Attributes { ATTRIBUTE:IOSet } ::= SET OF Attribute{{ IOSet }}
CRIAttributes ATTRIBUTE ::= {
... -- add any locally defined attributes here -- }
Attribute { ATTRIBUTE:IOSet } ::= SEQUENCE {
type ATTRIBUTE.&id({IOSet}),
values SET SIZE(1..MAX) OF ATTRIBUTE.&Type({IOSet}{@type})
}
等價寫法
CertificationRequest ::= SIGNED { EncodedCertificationRequestInfo }
(CONSTRAINED BY { -- Verify or sign encoded
-- CertificationRequestInfo -- })
EncodedCertificationRequestInfo ::=
TYPE-IDENTIFIER.&Type(CertificationRequestInfo)
SIGNED { ToBeSigned } ::= SEQUENCE {
toBeSigned ToBeSigned,
algorithm AlgorithmIdentifier { {SignatureAlgorithms} },
signature BIT STRING
}
