All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.ofdrw.gm.cert.PKCGenerate Maven / Gradle / Ivy

Go to download

符合《GMT 0031-2014 安全电子签章密码技术规范》与 《GB/T 38540-2020 信息安全技术 安全电子签章密码技术规范》的ASN1数据结构。

The newest version!
package org.ofdrw.gm.cert;

import org.bouncycastle.asn1.misc.MiscObjectIdentifiers;
import org.bouncycastle.asn1.misc.NetscapeCertType;
import org.bouncycastle.asn1.x500.X500Name;
import org.bouncycastle.asn1.x500.X500NameBuilder;
import org.bouncycastle.asn1.x500.style.BCStyle;
import org.bouncycastle.asn1.x509.BasicConstraints;
import org.bouncycastle.asn1.x509.ExtendedKeyUsage;
import org.bouncycastle.asn1.x509.Extension;
import org.bouncycastle.asn1.x509.KeyPurposeId;
import org.bouncycastle.cert.X509CertificateHolder;
import org.bouncycastle.cert.X509v3CertificateBuilder;
import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter;
import org.bouncycastle.cert.jcajce.JcaX509v3CertificateBuilder;
import org.bouncycastle.jce.X509KeyUsage;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.operator.ContentSigner;
import org.bouncycastle.operator.OperatorCreationException;
import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
import org.bouncycastle.pkcs.PKCS10CertificationRequest;
import org.bouncycastle.pkcs.PKCS10CertificationRequestBuilder;
import org.bouncycastle.pkcs.jcajce.JcaPKCS10CertificationRequest;
import org.bouncycastle.pkcs.jcajce.JcaPKCS10CertificationRequestBuilder;

import java.io.IOException;
import java.io.OutputStream;
import java.math.BigInteger;
import java.nio.file.Files;
import java.nio.file.Path;
import java.security.*;
import java.security.cert.Certificate;
import java.security.cert.X509Certificate;
import java.security.spec.ECGenParameterSpec;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Date;

/**
 * 生成测试的公私钥对和证书
 * 

* P12文件 *

* PK - Public Key and Private Key Pair *

* C - Certificate * * @author 权观宇 * @since 2020-04-21 09:37:10 */ public class PKCGenerate { static { Security.addProvider(new BouncyCastleProvider()); } /** * @return 证书请求识别名称 (也就是证书的Subject) */ public static X500Name TestND() { return new X500NameBuilder() // 国家代码 .addRDN(BCStyle.C, "CN") // 组织 .addRDN(BCStyle.O, "OFD R&W") // 省份 .addRDN(BCStyle.ST, "Zhejiang") // 地区 .addRDN(BCStyle.L, "Hangzhou") // 通用名称 .addRDN(BCStyle.CN, "Test Certificate") .build(); } /** * 生成SM2密钥对的证书请求(pkcs10格式) * * @param kp SM2密钥对 * @param subject 证书使用者 * @return 证书请求 * @throws OperatorCreationException 操作异常 */ public static PKCS10CertificationRequest CertRequest(KeyPair kp, X500Name subject) throws OperatorCreationException { // 构造请求信息,主要是由“实体”的DN和公钥构成 PKCS10CertificationRequestBuilder requestBuilder = new JcaPKCS10CertificationRequestBuilder(subject, kp.getPublic()); // 使用“实体”私钥对请求的信息进行签名,然后组装成ASN.1对象 return requestBuilder.build( new JcaContentSignerBuilder("SM3withSM2") .setProvider("BC") .build(kp.getPrivate())); } /** * 生成测试SM2密钥对 * * @return 密钥对 * @throws GeneralSecurityException 安全操作异常 */ public static KeyPair GenerateKeyPair() throws GeneralSecurityException { // 获取SM2椭圆曲线的参数 final ECGenParameterSpec sm2Spec = new ECGenParameterSpec("sm2p256v1"); // 获取一个椭圆曲线类型的密钥对生成器 final KeyPairGenerator kpg = KeyPairGenerator.getInstance("EC", new BouncyCastleProvider()); // 使用SM2参数初始化生成器 kpg.initialize(sm2Spec); // 使用SM2的算法区域初始化密钥生成器 kpg.initialize(sm2Spec, new SecureRandom()); // 获取密钥对 return kpg.generateKeyPair(); } /** * 签发证书 * * @param p10Obj 证书请求ASN1对象 * @param root CA根证书 * @param privateKey CA私钥 * @return X509证书对象 * @throws GeneralSecurityException 安全操作异常 * @throws IOException 文件读写异常 * @throws OperatorCreationException 操作异常 */ public static X509Certificate GenCert(PKCS10CertificationRequest p10Obj, Certificate root, PrivateKey privateKey) throws GeneralSecurityException, IOException, OperatorCreationException { JcaPKCS10CertificationRequest req = new JcaPKCS10CertificationRequest(p10Obj); // 从证书请求中获取到使用DN X500Name subject = req.getSubject(); // 取得根证书的Subject,签发证书的使用者就是根证书的使用者 X500Name issuer = new X509CertificateHolder(root.getEncoded()) .getSubject(); // 根据需求构造实体证书 X509v3CertificateBuilder certGen = new JcaX509v3CertificateBuilder( // 颁发者信息 issuer // 证书序列号 , BigInteger.valueOf(Instant.now().toEpochMilli()) // 证书生效日期 , Date.from(LocalDateTime.now().atZone(ZoneId.systemDefault()).toInstant()) // 证书失效日期 , Date.from(LocalDateTime.now().plusYears(2).atZone(ZoneId.systemDefault()).toInstant()) // 使用者信息 , subject // 证书公钥 , req.getPublicKey()) // 设置密钥用法 .addExtension(Extension.keyUsage, false , new X509KeyUsage(X509KeyUsage.digitalSignature | X509KeyUsage.nonRepudiation | X509KeyUsage.keyCertSign)) // 设置扩展密钥用法:客户端身份认证 .addExtension(Extension.extendedKeyUsage, false, new ExtendedKeyUsage(KeyPurposeId.id_kp_clientAuth)) // 基础约束,标识是否是CA证书,这里false标识为实体证书 .addExtension(Extension.basicConstraints, false, new BasicConstraints(false)) // Netscape Cert Type SSL客户端身份认证 .addExtension(MiscObjectIdentifiers.netscapeCertType, false, new NetscapeCertType(NetscapeCertType.sslClient)); // 5. 证书签名实现类 ContentSigner sigGen = new JcaContentSignerBuilder("SM3withSM2") .setProvider("BC") .build(privateKey); // 6. 签发证书 return new JcaX509CertificateConverter() .setProvider("BC") .getCertificate(certGen.build(sigGen)); } /** * 生成P12存储文件 *

* 存储公私钥对以及证书 * * @param pk 密钥对 * @param certs 证书链 * @param pwd P12密码 * @param outP 保存位置 * @throws GeneralSecurityException 安全异常 * @throws IOException IO异常 */ public static void SaveToPKCS12(KeyPair pk, Certificate[] certs, String pwd, Path outP) throws GeneralSecurityException, IOException { // 3. 以KeyStore保存 KeyStore store = KeyStore.getInstance("PKCS12", "BC"); // 3.1 初始化 store.load(null, null); char[] pwds = pwd.toCharArray(); // 3.2 写入证书以及公钥 store.setKeyEntry("private", pk.getPrivate(), pwds, certs); try (OutputStream out = Files.newOutputStream(outP);) { // 3.3 加密写入文件 store.store(out, pwds); } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy