Java bouncycastle API 創建 CSR 和簽發證書

引入 API

		<dependency>
            <groupId>org.bouncycastle</groupId>
            <artifactId>bcprov-jdk15on</artifactId>
            <version>1.64</version>
        </dependency>

創建 CSR

CSR,即證書請求文件(Certificate Signing Request)。生成 X509 數字證書前,一般先由用戶提交證書申請文件,然後由 CA 來簽發證書。

        // 創建密鑰對
        KeyPairGenerator gen = KeyPairGenerator.getInstance("RSA");
        gen.initialize(2048);
        KeyPair pair = gen.generateKeyPair();
        PrivateKey privateKey = pair.getPrivate();
        PublicKey publicKey = pair.getPublic();

        // 創建 CSR 對象
        X500Principal subject = new X500Principal("C=CName, ST=STName, L=LName, O=OName, OU=OUName, CN=CNName, [email protected]");
        ContentSigner signGen = new JcaContentSignerBuilder("SHA256withRSA").build(privateKey);
        PKCS10CertificationRequestBuilder builder = new JcaPKCS10CertificationRequestBuilder(subject, publicKey);
        // 添加 SAN 擴展
        ExtensionsGenerator extensionsGenerator = new ExtensionsGenerator();
        GeneralNames generalNames = new GeneralNames(new GeneralName[]{new GeneralName(GeneralName.rfc822Name, "ip=6.6.6.6"), new GeneralName(GeneralName.rfc822Name, "[email protected]")});
        extensionsGenerator.addExtension(Extension.subjectAlternativeName, false, generalNames);
        builder.addAttribute(PKCSObjectIdentifiers.pkcs_9_at_extensionRequest, extensionsGenerator.generate());
        // build csr
        PKCS10CertificationRequest csr = builder.build(signGen);
        // 輸出 PEM 格式的 CSR
        OutputStreamWriter output = new OutputStreamWriter(System.out);
        JcaPEMWriter pem = new JcaPEMWriter(output);
        pem.writeObject(csr);
        pem.close();

PEM 格式 CSR 示例如下:(PER 是對 DER 的簡單包裝

-----BEGIN CERTIFICATE REQUEST-----
MIIC5DCCAcwCAQAwgZ4xIjAgBgkqhkiG9w0BCQEWE3NlbnRoYWRldkBnbWFpbC5j
b20xGjAYBgNVBAMTEXd3dy5zZW50aGFkZXYuY29tMRMwEQYDVQQLEwpJbm5vdmF0
aW9uMRIwEAYDVQQKEwlTZW50aGFkZXYxEjAQBgNVBAcTCVRyb25kaGVpbTESMBAG
A1UECBMJVHJvbmRoZWltMQswCQYDVQQGEwJOTzCCASIwDQYJKoZIhvcNAQEBBQAD
ggEPADCCAQoCggEBAMkKvsCUp52lcmM//iJEV62yHzDS/ASwm0wmlbUR+OnxESA5
vsYYzqdxX/Ie+K4LqY/FKsnHwcj+l7PqIHPqgiDryMcfYFpmln31jJG6XPFmjBib
m0kl63G9T62EyoRYo7SFZq/wcdgEE0FTw4bnTyT5OED2cYRlozBXdnI0L9jZYv6b
R6ww4LD4cAkqq1TeKNt0lH5G7S8QqTIeobs7hYUgVXkKWhfrYrW0l4lYUuXC12sN
e/zGYClHoaFoasD9pzoFrVjDS9+a3JoInp22OxpQbBVchnOJ3yJr8PRS5Hzx5QYJ
TAYqUd8dsw372FhvnNlZJnSkAsxca7cfpCiL4ZECAwEAAaAAMA0GCSqGSIb3DQEB
BQUAA4IBAQDDTj7ZJaeRftrod5TuEPoDhH8SwCx/wX8aIYG3mjR+q8tJ6rYgPwqR
Du8ODOAgIRFC8Dk43taPhbL94+T+iyw+UJH1KGlf0cdfHvaPoTh6QqfIQHRXuq5H
hkb9g+DgG/uzIS0yQsviKCTwFOZkvaWMZQSlBkAzFf61NQ9ymjLRFnzUN3IBmxMU
VBBEVVchta79XtkQaOsHWaZPpuwvDEtrvvwjk6kIEsc7IU927nN1Vws9oDFsqrKl
ycNVfwjd0cgf5WsTbPnBjQdVSSdAWvJo1wLrv3GxGVUwi44TzVU0xvREYAmZknCW
kpMkr5KBOO3Prex5d0doD5MJhMvxHcSL
-----END CERTIFICATE REQUEST-----

利用 CSR 創建證書

首先,讀取、解析 CSR 文件:

        Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
        // 解析 PEM 格式的 CSR
        PKCS10CertificationRequest csr = null;
        ByteArrayInputStream pemStream = new ByteArrayInputStream(pem.getBytes(Charsets.UTF_8));
        Reader pemReader = new BufferedReader(new InputStreamReader(pemStream));
        PEMParser pemParser = new PEMParser(pemReader);

        Object parsedObj = pemParser.readObject();
        System.out.println("PemParser returned: " + parsedObj);
        if (parsedObj instanceof PKCS10CertificationRequest) {
            csr = (PKCS10CertificationRequest) parsedObj;
        }

利用 PKCS10CertificationRequest 槍法證書

		KeyPair rootPair = KeyUtil.generateKeyPair("RSA", 4096);
		// 私鑰用來前面
        PrivateKey issuePriveteKey = rootPair.getPrivate();
        X509Certificate rootCert = // 利用公鑰創建根證書,來簽發用戶證書

        X509v3CertificateBuilder certificateBuilder = new X509v3CertificateBuilder(
                new X500Name(rootCert.getSubjectDN().getName()),
                BigInteger.valueOf(666666666L),
                new Date(),
                new Date(System.currentTimeMillis() + 1000 * 86400 * 365L),
                pkcs10CertificationRequest.getSubject(),
                pkcs10CertificationRequest.getSubjectPublicKeyInfo()
        );

		// 讀取擴展信息
        Extensions extensions = null;
        for (Attribute attr : pkcs10CertificationRequest.getAttributes()) {
            if (PKCSObjectIdentifiers.pkcs_9_at_extensionRequest.equals(attr.getAttrType())) {
                extensions = Extensions.getInstance(attr.getAttributeValues()[0]);
                break;
            }
        }
        if (extensions != null) {
        // 添加 SAN 擴展
         certificateBuilder.addExtension(extensions.getExtension(Extension.subjectAlternativeName));
        }

        //添加crl擴展
        GeneralName[] names = new GeneralName[1];
        names[0] = new GeneralName(GeneralName.uniformResourceIdentifier, "http://www.ca.com/crl");
        GeneralNames gns = new GeneralNames(names);
        DistributionPointName pointName = new DistributionPointName(gns);
        GeneralNames crlIssuer = new GeneralNames(new GeneralName(new X500Name(rootCert.getSubjectDN().getName())));
        DistributionPoint[] points = new DistributionPoint[1];
        points[0] = new DistributionPoint(pointName, null, crlIssuer);
        certificateBuilder.addExtension(Extension.cRLDistributionPoints, false, new CRLDistPoint(points));

        //添加aia擴展
        AccessDescription[] accessDescriptions = new AccessDescription[2];
        accessDescriptions[0] = new AccessDescription(AccessDescription.id_ad_caIssuers, new GeneralName(GeneralName.uniformResourceIdentifier, "http://www.ca.com/root.crt"));
        accessDescriptions[1] = new AccessDescription(AccessDescription.id_ad_ocsp, new GeneralName(GeneralName.uniformResourceIdentifier, "http://ocsp.com/"));
        certificateBuilder.addExtension(Extension.authorityInfoAccess, false, new AuthorityInformationAccess(accessDescriptions));

        ContentSigner signer = new JcaContentSignerBuilder(HostCertificateConf.CERTIFICATE_SIGNATURE_ALGORITHM)
                .setProvider(Security.getProvider("BC")).build(issuePriveteKey);
        X509CertificateHolder holder = certificateBuilder.build(signer);
        X509Certificate cert = new JcaX509CertificateConverter()
                .setProvider(Security.getProvider( "BC")).getCertificate(holder);
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章