用户首先产生自己的密钥对,并将公共密钥及部分个人信息传送给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 }