本文章使用的环境
jdk1.8,spring-boot2.6.13
一、pom依赖
<dependency><groupId>org.bouncycastle</groupId><artifactId>bcprov-jdk15on</artifactId><version>1.49</version></dependency><dependency><groupId>org.bouncycastle</groupId><artifactId>bcpkix-jdk15on</artifactId><version>1.49</version></dependency>
二、生成证书代码
package com.lift.bright.pkcs;import org.bouncycastle.asn1.ASN1ObjectIdentifier;
import org.bouncycastle.asn1.ASN1Primitive;
import org.bouncycastle.asn1.x500.X500Name;
import org.bouncycastle.asn1.x509.*;
import org.bouncycastle.cert.X509CertificateHolder;
import org.bouncycastle.cert.X509v3CertificateBuilder;
import org.bouncycastle.cert.jcajce.JcaX509v3CertificateBuilder;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.operator.ContentSigner;
import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;import java.io.*;
import java.math.BigInteger;
import java.security.*;
import java.security.cert.Certificate;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.text.SimpleDateFormat;
import java.util.*;/*** @author bao* @date 2024/3/20 16:10*/
public class Pkcs {private static KeyPair getKey() throws NoSuchAlgorithmException {// 密钥对 生成器,RSA算法 生成的 提供者是 BouncyCastleKeyPairGenerator generator = KeyPairGenerator.getInstance("RSA", new BouncyCastleProvider());generator.initialize(1024); // 密钥长度 1024// 证书中的密钥 公钥和私钥KeyPair keyPair = generator.generateKeyPair();return keyPair;}/*** @param password 密码* @param issuerStr 颁发机构信息* @param subjectStr 使用者信息* @param certificateCRL 颁发地址* @return*/public static Map<String, byte[]> createCert(String password, String issuerStr, String subjectStr, String certificateCRL) {Map<String, byte[]> result = new HashMap<String, byte[]>();ByteArrayOutputStream out = null;try {// 生成JKS证书// KeyStore keyStore = KeyStore.getInstance("JKS");// 标志生成PKCS12证书KeyStore keyStore = KeyStore.getInstance("PKCS12", new BouncyCastleProvider());keyStore.load(null, null);KeyPair keyPair = getKey();// issuer与 subject相同的证书就是CA证书Certificate cert = generateCertificateV3(issuerStr, subjectStr, keyPair, result, certificateCRL, null);// cretkey随便写,标识别名keyStore.setKeyEntry("cretkey", keyPair.getPrivate(), password.toCharArray(), new Certificate[] { cert });out = new ByteArrayOutputStream();cert.verify(keyPair.getPublic());keyStore.store(out, password.toCharArray());byte[] keyStoreData = out.toByteArray();result.put("keyStoreData", keyStoreData);return result;} catch (Exception e) {e.printStackTrace();} finally {if (out != null) {try {out.close();} catch (IOException e) {}}}return result;}/*** @param issuerStr* @param subjectStr* @param keyPair* @param result* @param certificateCRL* @param extensions* @return*/public static Certificate generateCertificateV3(String issuerStr, String subjectStr, KeyPair keyPair, Map<String, byte[]> result,String certificateCRL, List<Extension> extensions) {ByteArrayInputStream bout = null;X509Certificate cert = null;try {PublicKey publicKey = keyPair.getPublic();PrivateKey privateKey = keyPair.getPrivate();Date notBefore = new Date();Calendar rightNow = Calendar.getInstance();rightNow.setTime(notBefore);// 日期加1年rightNow.add(Calendar.YEAR, 1);Date notAfter = rightNow.getTime();// 证书序列号BigInteger serial = BigInteger.probablePrime(256, new Random());X509v3CertificateBuilder builder = new JcaX509v3CertificateBuilder(new X500Name(issuerStr), serial, notBefore, notAfter,new X500Name(subjectStr), publicKey);JcaContentSignerBuilder jBuilder = new JcaContentSignerBuilder( "SHA1withRSA");SecureRandom secureRandom = new SecureRandom();jBuilder.setSecureRandom(secureRandom);ContentSigner singer = jBuilder.setProvider( new BouncyCastleProvider()).build(privateKey);// 分发点ASN1ObjectIdentifier cRLDistributionPoints = new ASN1ObjectIdentifier( "2.5.29.31");GeneralName generalName = new GeneralName( GeneralName.uniformResourceIdentifier, certificateCRL);GeneralNames seneralNames = new GeneralNames(generalName);DistributionPointName distributionPoint = new DistributionPointName( seneralNames);DistributionPoint[] points = new DistributionPoint[1];points[0] = new DistributionPoint(distributionPoint, null, null);CRLDistPoint cRLDistPoint = new CRLDistPoint(points);builder.addExtension(cRLDistributionPoints, true, cRLDistPoint);// 用途ASN1ObjectIdentifier keyUsage = new ASN1ObjectIdentifier( "2.5.29.15");// | KeyUsage.nonRepudiation | KeyUsage.keyCertSignbuilder.addExtension(keyUsage, true, new KeyUsage( KeyUsage.digitalSignature | KeyUsage.keyEncipherment));// 基本限制 X509Extension.javaASN1ObjectIdentifier basicConstraints = new ASN1ObjectIdentifier("2.5.29.19");builder.addExtension(basicConstraints, true, new BasicConstraints(true));// privKey:使用自己的私钥进行签名,CA证书if (extensions != null){for (Extension ext : extensions) {builder.addExtension(new ASN1ObjectIdentifier(ext.getOid()),ext.isCritical(),ASN1Primitive.fromByteArray(ext.getValue()));}}X509CertificateHolder holder = builder.build(singer);CertificateFactory cf = CertificateFactory.getInstance("X.509");bout = new ByteArrayInputStream(holder.toASN1Structure() .getEncoded());cert = (X509Certificate) cf.generateCertificate(bout);byte[] certBuf = holder.getEncoded();SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");// 证书数据result.put("certificateData", certBuf);//公钥result.put("publicKey", publicKey.getEncoded());//私钥result.put("privateKey", privateKey.getEncoded());//证书有效开始时间result.put("notBefore", format.format(notBefore).getBytes("utf-8"));//证书有效结束时间result.put("notAfter", format.format(notAfter).getBytes("utf-8"));} catch (Exception e) {e.printStackTrace();} finally {if (bout != null) {try {bout.close();} catch (IOException e) {}}}return cert;}public class Extension {private String oid;private boolean critical;private byte[] value;public String getOid() {return oid;}public byte[] getValue() {return value;}public boolean isCritical() {return critical;}}public static void main(String[] args) throws Exception{// CN: 名字与姓氏 OU : 组织单位名称// O :组织名称 L : 城市或区域名称 E : 电子邮件// ST: 州或省份名称 C: 单位的两字母国家代码String issuerStr = "CN=ibright.com,OU=ibright.com,O=ibright.com,C=CN,E=bnmjstu@ibright.com,L=BeiJin,ST=BeiJin";String subjectStr = "CN=ibright.com,OU=ibright.com,O=ibright.com,C=CN,E=bnmjstu@ibright.com,L=BeiJin,ST=BeiJin";String certificateCRL = "https://www.ibright.com/";//创建证书Map<String, byte[]> result = createCert("ibright2014", issuerStr, subjectStr, certificateCRL);//获取资源文件路径String resourcePath = "./src/main/resources/";FileOutputStream outPutStream = new FileOutputStream(resourcePath + "./ibright.p12"); // ca.jksoutPutStream.write(result.get("keyStoreData"));outPutStream.close();FileOutputStream fos = new FileOutputStream(new File(resourcePath + "./ibright.cer"));fos.write(result.get("certificateData"));fos.flush();fos.close();}
}
三、生成结果
四、完整项目地址
bnmjstu / gen-pkcs · GitCode