From c46455ce9621eeb0dc3efac6278b3f9cb141f289 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=A0=E5=BF=A0=E6=BA=90?= Date: Thu, 2 Nov 2023 11:36:56 +0800 Subject: [PATCH] =?UTF-8?q?feat(=E6=96=B0=E5=A2=9E=E4=BB=8E=E5=A4=96?= =?UTF-8?q?=E9=83=A8=E7=AD=BE=E5=90=8D=20=E7=94=9F=E6=88=90CSR)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/org/zz/gmhelper/cert/CommonUtil.java | 44 ++++++++++++++++++- .../zz/gmhelper/cert/SM2X509CertMaker.java | 2 +- .../org/zz/gmhelper/test/util/FileUtil.java | 16 +------ 3 files changed, 45 insertions(+), 17 deletions(-) diff --git a/src/main/java/org/zz/gmhelper/cert/CommonUtil.java b/src/main/java/org/zz/gmhelper/cert/CommonUtil.java index e6b522d..60f642b 100644 --- a/src/main/java/org/zz/gmhelper/cert/CommonUtil.java +++ b/src/main/java/org/zz/gmhelper/cert/CommonUtil.java @@ -1,10 +1,18 @@ package org.zz.gmhelper.cert; +import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1ObjectIdentifier; +import org.bouncycastle.asn1.DERBitString; +import org.bouncycastle.asn1.DERSet; +import org.bouncycastle.asn1.pkcs.CertificationRequest; +import org.bouncycastle.asn1.pkcs.CertificationRequestInfo; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.asn1.x500.X500NameBuilder; import org.bouncycastle.asn1.x500.style.BCStyle; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; +import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; +import org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPrivateKey; +import org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPublicKey; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.operator.ContentSigner; import org.bouncycastle.operator.DefaultDigestAlgorithmIdentifierFinder; @@ -14,6 +22,7 @@ import org.bouncycastle.pkcs.PKCS10CertificationRequest; import org.bouncycastle.pkcs.PKCS10CertificationRequestBuilder; import org.bouncycastle.pkcs.jcajce.JcaPKCS10CertificationRequestBuilder; +import org.zz.gmhelper.SM2Util; import org.zz.gmhelper.cert.exception.InvalidX500NameException; import java.security.PrivateKey; @@ -49,14 +58,45 @@ public static X500Name buildX500Name(Map names) throws InvalidX5 } } + + /** + * 生成CSR + * + * @param subject 主题信息 + * @param pubKey 公钥 + * @param priKey 私钥 + * @param signAlgo 签名算法 + * @return CSR + */ public static PKCS10CertificationRequest createCSR(X500Name subject, SM2PublicKey pubKey, PrivateKey priKey, - String signAlgo) throws OperatorCreationException { + String signAlgo) throws OperatorCreationException { PKCS10CertificationRequestBuilder csrBuilder = new JcaPKCS10CertificationRequestBuilder(subject, pubKey); ContentSigner signerBuilder = new JcaContentSignerBuilder(signAlgo) - .setProvider(BouncyCastleProvider.PROVIDER_NAME).build(priKey); + .setProvider(BouncyCastleProvider.PROVIDER_NAME).build(priKey); return csrBuilder.build(signerBuilder); } + /** + * 生成CSR + * 实际业务大部部分情况私钥是在UKey中,只能调用UKey的签名接口,因此上面的方法不能使用,本方法是为了解决这个问题,从外部签名完毕,传入签名值就可以 + * 需要签名的对象为本方法中的 info ,取info.getEncoded()后签名 + * @param subject 主题信息 + * @param pubKey 公钥 + * @param signAlgo 签名算法 + * @param sign 签名值 对本方法中的 info ,取info.getEncoded()后签名 + * @return CSR + */ + public static PKCS10CertificationRequest createCSR(X500Name subject, SM2PublicKey pubKey, String signAlgo, byte[] sign) throws OperatorCreationException { + //info + SM2PublicKey sm2SubPub = new SM2PublicKey(pubKey.getAlgorithm(), pubKey); + ASN1EncodableVector v = new ASN1EncodableVector(); + CertificationRequestInfo info = new CertificationRequestInfo(subject, SubjectPublicKeyInfo.getInstance(sm2SubPub.getEncoded()), new DERSet(v)); + AlgorithmIdentifier algorithmIdentifier = new DefaultSignatureAlgorithmIdentifierFinder().find(signAlgo); + CertificationRequest certificationRequest = new CertificationRequest(info, algorithmIdentifier, new DERBitString(sign)); + return new PKCS10CertificationRequest(certificationRequest); + } + + public static AlgorithmIdentifier findSignatureAlgorithmIdentifier(String algoName) { DefaultSignatureAlgorithmIdentifierFinder sigFinder = new DefaultSignatureAlgorithmIdentifierFinder(); return sigFinder.find(algoName); diff --git a/src/main/java/org/zz/gmhelper/cert/SM2X509CertMaker.java b/src/main/java/org/zz/gmhelper/cert/SM2X509CertMaker.java index 61767d3..6c005c7 100644 --- a/src/main/java/org/zz/gmhelper/cert/SM2X509CertMaker.java +++ b/src/main/java/org/zz/gmhelper/cert/SM2X509CertMaker.java @@ -120,7 +120,7 @@ public X509Certificate makeEndEntityCert(byte[] csr, } /** - * @param isCA 是否是颁发给CA的证书 + * @param certLevel 证书级别 {@link CertLevel} * @param keyUsage 证书用途 * @param csr CSR * @return diff --git a/src/test/java/org/zz/gmhelper/test/util/FileUtil.java b/src/test/java/org/zz/gmhelper/test/util/FileUtil.java index c7dd603..f47cce2 100644 --- a/src/test/java/org/zz/gmhelper/test/util/FileUtil.java +++ b/src/test/java/org/zz/gmhelper/test/util/FileUtil.java @@ -5,29 +5,17 @@ public class FileUtil { public static void writeFile(String filePath, byte[] data) throws IOException { - RandomAccessFile raf = null; - try { - raf = new RandomAccessFile(filePath, "rw"); + try (RandomAccessFile raf = new RandomAccessFile(filePath, "rw")) { raf.write(data); - } finally { - if (raf != null) { - raf.close(); - } } } public static byte[] readFile(String filePath) throws IOException { - RandomAccessFile raf = null; byte[] data; - try { - raf = new RandomAccessFile(filePath, "r"); + try (RandomAccessFile raf = new RandomAccessFile(filePath, "r")) { data = new byte[(int) raf.length()]; raf.read(data); return data; - } finally { - if (raf != null) { - raf.close(); - } } } }