package com.qianwen.license.keystore; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.FileReader; import java.math.BigInteger; import java.security.KeyFactory; import java.security.KeyStore; import java.security.PrivateKey; import java.security.PublicKey; import java.security.Security; import java.security.cert.Certificate; import java.security.cert.CertificateFactory; import java.security.cert.X509Certificate; import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.jce.provider.PEMUtil; import org.bouncycastle.openssl.PEMParser; import org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter; import org.bouncycastle.util.io.pem.PemObject; import org.bouncycastle.util.io.pem.PemReader; import cn.hutool.core.date.DateField; import cn.hutool.core.date.DateTime; import cn.hutool.core.date.DateUtil; import cn.hutool.core.util.RandomUtil; import cn.hutool.core.util.StrUtil; import cn.hutool.crypto.KeyUtil; import cn.hutool.crypto.PemUtil; public class PubKeyGenDemo { static String root = "d:/cert"; /** * 自签名根证书私钥保存路径 /ca/ca-private.key */ private static final String CA_PRIVATE_KEY_FILE_PATH = StrUtil.format("{}/ca/ca-private.key", root); /** * 自签名根证书公钥保存路径 /ca/ca-public.key */ private static final String CA_PUBLIC_KEY_FILE_PATH = StrUtil.format("{}/ca/ca-public.key", root); /** * 自签名根证书保存路径ca/ca.cer */ private static final String CA_CERTIFICATE_FILE_PATH = StrUtil.format("{}/ca/ca.cer", root); /** * 自签名证书私钥保存路径self/self-private.key */ private static final String SELF_SIGNED_PRIVATE_KEY_FILE_PATH = StrUtil.format("{}/self/self-private.key", root); /** * 自签名证书公钥保存路径self/self-public.key */ private static final String SELF_SIGNED_PUBLIC_KEY_FILE_PATH = StrUtil.format("{}/self/self-public.key", root); /** * 自签名证书保存路径 self/self.cer */ private static final String SELF_SIGNED_CERTIFICATE_FILE_PATH = StrUtil.format("{}/self/self.cer", root); /** * pkcs12 格式证书保存路径 self/self.p12 */ private static final String SELF_SIGNED_PKCS12_FILE_PATH = StrUtil.format("{}/self/self.p12", root); /** * pkcs12 公钥库格式证书保存路径 */ private static final String SELF_SIGNED_PUBLIC_PKCS12_FILE_PATH = StrUtil.format("{}/self/publicself.p12", root); /** * pkcs12 格式证书密码 */ private static final String SELF_SIGNED_PKCS12_CERTIFICATE_PASSWORD = "a1b2c3"; public static void main(String[] args) throws Throwable { //Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider()); toCaCertificate(); toSelfSignedCertificate(); toPrivatePkcs12Store(); toPublicPkcs12Store(); } /** * 生成根证书及其密钥对,保存位2个key文件和一个ca.cer,这个在后续只是一个颁发者的属性需要使用 * @throws Throwable */ public static void toCaCertificate() throws Throwable { //根证书主题信息 X500Name subject = new SubjectBuilder() .setCn("yangys") .setO("My CA organization") .setOu("My CA organizational unit name") .setC("My CA country code") .setSt("My CA state, or province name") .setL("My CA locality name") .build(); //根证书颁发者信息,即自身 X500Name issuer = subject; //根证书有效期 DateTime notBefore = DateUtil.yesterday(); DateTime notAfter = DateUtil.offset(notBefore, DateField.YEAR, 10); CertificateInfo certificateInfo = new CertificateInfo(); certificateInfo.setSerial(BigInteger.valueOf(RandomUtil.randomLong(1L, Long.MAX_VALUE))); certificateInfo.setIssuer(issuer); certificateInfo.setSubject(subject); certificateInfo.setNotBefore(notBefore); certificateInfo.setNotAfter(notAfter); certificateInfo.setKeyAlgorithm(X509CertificateConstants.KEY_ALGORITHM); certificateInfo.setSignAlgorithm(X509CertificateConstants.SIGN_ALGORITHM); //生成根证书及其密钥对 KeyAndCertificate keyAndCertificate = CertificateUtils.generateCertificate(certificateInfo, null); //保存根证书及其密钥对到磁盘 CertificateUtils.save(keyAndCertificate.getPrivateKey(), CA_PRIVATE_KEY_FILE_PATH); CertificateUtils.save(keyAndCertificate.getPublicKey(), CA_PUBLIC_KEY_FILE_PATH); CertificateUtils.save(keyAndCertificate.getCertificate(), CA_CERTIFICATE_FILE_PATH); } /** * 生成自签名证书及其密钥对 * @throws Throwable */ public static void toSelfSignedCertificate() throws Throwable { //根证书私钥 PrivateKey caPrivateKey; //从磁盘加载根证书私钥 try(FileInputStream fileInputStream = new FileInputStream(CA_PRIVATE_KEY_FILE_PATH);) { caPrivateKey = PemUtil.readPemPrivateKey(fileInputStream); } //从磁盘加载根证书 X509Certificate caCertificate; try(FileInputStream fileInputStream = new FileInputStream(CA_CERTIFICATE_FILE_PATH);) { caCertificate = (X509Certificate) KeyUtil.readX509Certificate(fileInputStream); } //证书颁发者信息 X500Name issuer = new X500Name(caCertificate.getIssuerX500Principal().getName()); //证书主题信息 X500Name subject = new SubjectBuilder() .setCn("My common name") .setO("My organization") .setOu("My organizational unit name") .setC("My country code") .setSt("My state, or province name") .setL("My locality name") .build(); //证书有效期 DateTime notBefore = DateUtil.yesterday(); DateTime notAfter = DateUtil.offset(notBefore, DateField.YEAR, 10); CertificateInfo certificateInfo = new CertificateInfo(); certificateInfo.setSerial(BigInteger.valueOf(RandomUtil.randomLong(1L, Long.MAX_VALUE))); certificateInfo.setIssuer(issuer); certificateInfo.setSubject(subject); certificateInfo.setNotBefore(notBefore); certificateInfo.setNotAfter(notAfter); certificateInfo.setKeyAlgorithm(X509CertificateConstants.KEY_ALGORITHM); certificateInfo.setSignAlgorithm(X509CertificateConstants.SIGN_ALGORITHM); //生成自签名证书及其密钥对 KeyAndCertificate keyAndCertificate = CertificateUtils.generateCertificate(certificateInfo, caPrivateKey); //保存自签名证书及其密钥对到磁盘 CertificateUtils.save(keyAndCertificate.getPrivateKey(), SELF_SIGNED_PRIVATE_KEY_FILE_PATH); CertificateUtils.save(keyAndCertificate.getPublicKey(), SELF_SIGNED_PUBLIC_KEY_FILE_PATH); CertificateUtils.save(keyAndCertificate.getCertificate(), SELF_SIGNED_CERTIFICATE_FILE_PATH); } /** * 生成 pkcs12 格式证书,根据情况,可胜场公,私2中证书 * @throws Exception */ public static void toPrivatePkcs12Store() throws Exception { char[] password = SELF_SIGNED_PKCS12_CERTIFICATE_PASSWORD.toCharArray(); //证书私钥 PrivateKey privateKey; //从磁盘加载证书私钥 try(FileInputStream fileInputStream = new FileInputStream(SELF_SIGNED_PRIVATE_KEY_FILE_PATH)) { privateKey = PemUtil.readPemPrivateKey(fileInputStream); } //证书 Certificate certificate; //从磁盘加载证书 try(FileInputStream fileInputStream = new FileInputStream(SELF_SIGNED_CERTIFICATE_FILE_PATH)) { certificate = KeyUtil.readX509Certificate(fileInputStream); } KeyStore pkcs12 = KeyStore.getInstance("pkcs12"); pkcs12.load(null, password); pkcs12.setKeyEntry("myPrivate", privateKey, password, new Certificate[] {certificate}); try(FileOutputStream fileOutputStream = new FileOutputStream(SELF_SIGNED_PKCS12_FILE_PATH)) { pkcs12.store(fileOutputStream, password); } } public static void toPublicPkcs12Store() throws Exception { char[] password = SELF_SIGNED_PKCS12_CERTIFICATE_PASSWORD.toCharArray(); // 加载证书 Certificate certificate; //从磁盘加载证书,就是用keytool从私钥导出的证书 try(FileInputStream fileInputStream = new FileInputStream(SELF_SIGNED_CERTIFICATE_FILE_PATH)) { certificate = KeyUtil.readX509Certificate(fileInputStream); } KeyStore pkcs12 = KeyStore.getInstance("pkcs12");//自己改的, "BC" pkcs12.load(null, password); String alias = "myPublicKey"; pkcs12.setCertificateEntry(alias, certificate); //pkcs12.setKeyEntry("myPublicKey", publicKey, password, new Certificate[] {certificate}); try(FileOutputStream fileOutputStream = new FileOutputStream(SELF_SIGNED_PUBLIC_PKCS12_FILE_PATH)) { pkcs12.store(fileOutputStream, password); } } }