package cn.byzk.common.asn1;
import cn.byzk.common.asn1.util.ExtensionKeyUseUtil;
import cn.byzk.common.util.gmhelper.GMBaseUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.HexUtil;
import lombok.Data;
import org.bouncycastle.asn1.*;
import org.bouncycastle.asn1.misc.MiscObjectIdentifiers;
import org.bouncycastle.asn1.x500.X500Name;
import org.bouncycastle.asn1.x500.X500NameBuilder;
import org.bouncycastle.asn1.x500.style.BCStyle;
import org.bouncycastle.asn1.x509.*;
import org.bouncycastle.asn1.x9.X9ObjectIdentifiers;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigInteger;
import java.security.cert.CertificateEncodingException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
/**
* @author 会飞的大象 2023-08-25 .
*/
@Data
public class Asn1CertTest extends GMBaseUtil {
/**
* sm3摘要 sm2签名.
*/
public static String SM3WithSM2 = "1.2.156.10197.1.501";
//公钥.
private static String PUBLIC_SIGN = "1.2.156.10197.1.301";
public static void main(String[] args) throws IOException {
// TBSCertificate tbsCert;
// AlgorithmIdentifier sigAlgId;
// ASN1BitString sig;
// Certificate certificate=new Certificate();
// ASN1Integer version;
// ASN1Integer serialNumber;
// AlgorithmIdentifier signature;
// X500Name issuer;
// Time startDate, endDate;
// X500Name subject;
// SubjectPublicKeyInfo subjectPublicKeyInfo;
// ASN1BitString issuerUniqueId;
// ASN1BitString subjectUniqueId;
// Extensions extensions;
//签名算法.
AlgorithmIdentifier sigAlgId = new AlgorithmIdentifier(new ASN1ObjectIdentifier(SM3WithSM2), DERNull.INSTANCE);
//签名值.
ASN1BitString sig = new DERBitString(HexUtil.decodeHex("3045022052e8cc50b508eb1c1865a3f7fed009131800e6a52801c4f5687f7dc80afedbff022100def235cfaf944d0970588131cf79000436f680bcb73f4932250d12d62dc00df7"));
// TBSCertificate tbsCert;
V3TBSCertificateGenerator v3TBSCertificateGenerator = new V3TBSCertificateGenerator();
//v3的值为2.
ASN1Integer version = new ASN1Integer(2);
//证书序列号.
ASN1Integer serialNumber = new ASN1Integer(new BigInteger("13030000020117", 16));
v3TBSCertificateGenerator.setSerialNumber(serialNumber);
//签名算法.
ASN1ObjectIdentifier signature = new ASN1ObjectIdentifier(SM3WithSM2);
v3TBSCertificateGenerator.setSignature(new AlgorithmIdentifier(signature, DERNull.INSTANCE));
//issuser项目.
X500NameBuilder issuerBuilder = new X500NameBuilder();
issuerBuilder.addRDN(BCStyle.C, "CN");
issuerBuilder.addRDN(BCStyle.CN, "税务测试CA1(SM2)");
X500Name issuer = issuerBuilder.build();
v3TBSCertificateGenerator.setIssuer(issuer);
//证书开始与结束时间.
//"2023011800"
//"2028011800"
v3TBSCertificateGenerator.setStartDate(new DERUTCTime("230118000000Z"));
v3TBSCertificateGenerator.setEndDate(new DERUTCTime("280118000000Z"));
X500NameBuilder subjectBuilder = new X500NameBuilder();
subjectBuilder.addRDN(BCStyle.C, "CN");
subjectBuilder.addRDN(BCStyle.OU, "国家税务总局山东省税务局");
subjectBuilder.addRDN(BCStyle.CN, "0.54 SM2审计员2");
X500Name subject = subjectBuilder.build();
v3TBSCertificateGenerator.setSubject(subject);
// TODO: 2023/8/25 公钥信息.64位字节
//公钥标识与算法 SM3WithSM2
AlgorithmIdentifier publicKeyInfoAlgId = new AlgorithmIdentifier(X9ObjectIdentifiers.id_ecPublicKey, new ASN1ObjectIdentifier(PUBLIC_SIGN));
SubjectPublicKeyInfo subjectPublicKeyInfo = new SubjectPublicKeyInfo(publicKeyInfoAlgId, HexUtil.decodeHex("0477de607582267420ef39a1860f62803198831fb5c90c788aafcfd54a57f1e8ddd282d9bbfd1a4120829ad414995e5540778634c783cd218f486214154855f3a9"));
v3TBSCertificateGenerator.setSubjectPublicKeyInfo(subjectPublicKeyInfo);
//非必填,如果出现,版本必须为v2或v3 目前不用
// v3TBSCertificateGenerator.setIssuerUniqueID(new DERBitString("v3".getBytes()));
// 非必填,如果出现,版本必须为v2或v3 目前不用
// v3TBSCertificateGenerator.setSubjectUniqueID(new DERBitString("v3".getBytes()));
//拓展项.
ExtensionsGenerator extensionsGenerator = new ExtensionsGenerator();
//密钥用法 以最后一个字节的二进制计算0000000,八个0从左到右依次为0到7,当为1时候说明选中了。
//digitalSignature 0
//nonRepudiation 1
//keyEncipherment 2
//dataEncipherment 3
//keyAgreement 4
//keyCertSign 5
//cRLSign 6
//encipherOnlydecipherOnly 7
//证书类型.
//ssl
byte[] netscapeCertTypeByte = ExtensionKeyUseUtil.getExtensionKeyUtil(0, 2);
//2.16.840.1.113730.1.1
extensionsGenerator.addExtension(MiscObjectIdentifiers.netscapeCertType, false, netscapeCertTypeByte);
/**
* 密钥用法.
*/
boolean isSignCert = true;
// TODO: 2023/8/28 后续可以根据此进行优化.
byte[] keyUsageByte = null;
if (isSignCert) {
//签名证书
keyUsageByte = ExtensionKeyUseUtil.getExtensionKeyUtil(0, 1);
} else {
//加密证书38
keyUsageByte = ExtensionKeyUseUtil.getExtensionKeyUtil(2, 3, 4);
}
//2.5.29.15 密钥用途.
extensionsGenerator.addExtension(Extension.keyUsage, true, keyUsageByte);
//2.5.9.19 基本约束
extensionsGenerator.addExtension(Extension.basicConstraints, false,
new byte[]{0x30, 0x00});
//2.5.29.37 密钥增强用法
ASN1EncodableVector extendedKeyUsageVector = new ASN1EncodableVector();
//客户端身份验证
extendedKeyUsageVector.add(new ASN1ObjectIdentifier("1.3.6.1.5.5.7.3.2"));
//1.3.6.1.5.5.7.3.4
extendedKeyUsageVector.add(new ASN1ObjectIdentifier("1.3.6.1.5.5.7.3.4"));
//1.3.6.1.4.1.311.20.2.2
extendedKeyUsageVector.add(new ASN1ObjectIdentifier("1.3.6.1.4.1.311.20.2.2"));
extensionsGenerator.addExtension(Extension.extendedKeyUsage, false,
new DLSequence(extendedKeyUsageVector));
//2.5.29.35 授权密钥标识符
ASN1EncodableVector authorityKeyVector = new ASN1EncodableVector();
DLTaggedObject dlTaggedObject = new DLTaggedObject(false, 0,
new DEROctetString(HexUtil.decodeHex("51c8c0b592e7da27266c91c56d3d482cb2105123")));
authorityKeyVector.add(dlTaggedObject);
DLSequence authorityDLSequence = new DLSequence(authorityKeyVector);
extensionsGenerator.addExtension(Extension.authorityKeyIdentifier, false,
authorityDLSequence);
//2.5.29.14 使用者密钥标识 不一致
extensionsGenerator.addExtension(Extension.subjectKeyIdentifier, false,
new DEROctetString(HexUtil.decodeHex("cbbd413b03c58a9e68e710ede7ad215069be5adc")));
//2.5.29.32 证书政策
ASN1EncodableVector certificatePoliciesVector = new ASN1EncodableVector();
ASN1EncodableVector certificatePoliciesV1 = new ASN1EncodableVector();
certificatePoliciesV1.add(new ASN1ObjectIdentifier("2.5.29.32.0"));
ASN1EncodableVector certificatePoliciesV2 = new ASN1EncodableVector();
ASN1EncodableVector certificatePoliciesV3 = new ASN1EncodableVector();
certificatePoliciesV3.add(new ASN1ObjectIdentifier("1.3.6.1.5.5.7.2.1"));
certificatePoliciesV3.add(new DERIA5String("http://cps.chinatax.gov.cn"));
certificatePoliciesV2.add(new DLSequence(certificatePoliciesV3));
certificatePoliciesV1.add(new DLSequence(certificatePoliciesV2));
certificatePoliciesVector.add(new DLSequence(certificatePoliciesV1));
extensionsGenerator.addExtension(Extension.certificatePolicies, false, new DLSequence(certificatePoliciesVector));
//2.5.29.31 CRL分发点.
ASN1EncodableVector cRLDistributionPointsVector = new ASN1EncodableVector();
ASN1EncodableVector cRLDistributionPointsV1 = new ASN1EncodableVector();
ASN1EncodableVector cRLDistributionPointsV2 = new ASN1EncodableVector();
cRLDistributionPointsV1.add(new DLTaggedObject(0,
new DLTaggedObject(0, new DLTaggedObject(false, 6,
new DEROctetString("ldap://127.0.0.1:2389/cn=crl1303,ou=crl13,ou=crl,c=cn?certificateRevocationList?base?cn=crl1303".getBytes())))));
cRLDistributionPointsV2.add(new DLTaggedObject(0,
new DLTaggedObject(0, new DLTaggedObject(false, 6,
new DEROctetString("ldap://chinatax.gov.cn:2389/cn=crl1303,ou=crl13,ou=crl,c=cn?certificateRevocationList?base?cn=crl1303".getBytes())))));
cRLDistributionPointsVector.add(new DLSequence(cRLDistributionPointsV1));
cRLDistributionPointsVector.add(new DLSequence(cRLDistributionPointsV2));
extensionsGenerator.addExtension(Extension.cRLDistributionPoints, false, new DLSequence(cRLDistributionPointsVector));
//1.3.6.1.5.5.7.1.1 授权信息访问
ASN1EncodableVector authorityInfoAccessVector = new ASN1EncodableVector();
ASN1EncodableVector authorityInfoAccessV1 = new ASN1EncodableVector();
ASN1EncodableVector authorityInfoAccessV2 = new ASN1EncodableVector();
//1.3.6.1.5.5.7.48.1
authorityInfoAccessV1.add(X509ObjectIdentifiers.id_ad_ocsp);
authorityInfoAccessV1.add(new DLTaggedObject(false, 6,
new DEROctetString("http://127.0.0.1:6588/".getBytes())));
//1.3.6.1.5.5.7.48.1
authorityInfoAccessV2.add(X509ObjectIdentifiers.id_ad_ocsp);
authorityInfoAccessV2.add(new DLTaggedObject(false, 6,
new DEROctetString("http://ocsp.chinatax.gov.cn:8800/".getBytes())));
authorityInfoAccessVector.add(new DLSequence(authorityInfoAccessV1));
authorityInfoAccessVector.add(new DLSequence(authorityInfoAccessV2));
extensionsGenerator.addExtension(Extension.authorityInfoAccess, false, new DLSequence(authorityInfoAccessVector));
//1.3.6.1.4.1.5315.100.5.8
extensionsGenerator.addExtension(new ASN1ObjectIdentifier("1.3.6.1.4.1.5315.100.5.8"),
false, new DERUTF8String("03-99000000000253"));
//1.3.6.1.4.1.5315.100.5.9
extensionsGenerator.addExtension(new ASN1ObjectIdentifier("1.3.6.1.4.1.5315.100.5.9"),
false, new DERUTF8String("03-99000000000253"));
//1.3.6.1.4.1.5315.100.2.1
extensionsGenerator.addExtension(new ASN1ObjectIdentifier("1.3.6.1.4.1.5315.100.2.1"),
false, new DERUTF8String("20"));
//1.2.86.11.7.2
extensionsGenerator.addExtension(new ASN1ObjectIdentifier("1.2.86.11.7.2"),
false, new DERUTF8String("山东省税务局"));
//1.2.86.11.7.3
extensionsGenerator.addExtension(new ASN1ObjectIdentifier("1.2.86.11.7.3"),
false, new DERUTF8String("13700000000"));
//1.2.86.11.7.5
extensionsGenerator.addExtension(new ASN1ObjectIdentifier("1.2.86.11.7.5"),
false, new DERUTF8String("99000000000253"));
//2.16.840.1.113731.9
extensionsGenerator.addExtension(new ASN1ObjectIdentifier("2.16.840.1.113731.9"),
false, new DERUTF8String("0100010000000203"));
//构造.
Extensions extensions = extensionsGenerator.generate();
v3TBSCertificateGenerator.setExtensions(extensions);
//合并证书数据.
TBSCertificate tbsCert = v3TBSCertificateGenerator.generateTBSCertificate();
//最终证书.
ASN1EncodableVector certificateVector = new ASN1EncodableVector();
certificateVector.add(tbsCert);
certificateVector.add(sigAlgId);
certificateVector.add(sig);
ASN1Sequence asn1Encodables = new DERSequence(certificateVector);
Certificate c1 = Certificate.getInstance(asn1Encodables);
try {
FileUtil.writeBytes(c1.getEncoded(), "C:\\Users\\liang\\Desktop\\ofd-test\\java生成的.cer");
} catch (IOException e) {
e.printStackTrace();
}
byte[] bytes = FileUtil.readBytes("C:\\Users\\liang\\Desktop\\ofd-test\\家里ra发的证书.cer");
X509Certificate instance1 = null;
try {
InputStream stream = new ByteArrayInputStream(bytes);
CertificateFactory CERTIFICATE_FACTORY = CertificateFactory.getInstance("X.509", "BC");
instance1 = (X509Certificate) CERTIFICATE_FACTORY.generateCertificate(stream);
} catch (Exception e) {
e.printStackTrace();
}
Certificate c2 = null;
try {
c2 = Certificate.getInstance(instance1.getEncoded());
} catch (CertificateEncodingException e) {
e.printStackTrace();
}
Extensions extensions1 = c1.getTBSCertificate().getExtensions();
Extensions extensions2 = c2.getTBSCertificate().getExtensions();
SubjectPublicKeyInfo subjectPublicKeyInfo1 = c1.getTBSCertificate().getSubjectPublicKeyInfo();
SubjectPublicKeyInfo subjectPublicKeyInfo2 = c2.getTBSCertificate().getSubjectPublicKeyInfo();
System.out.println("测试");
}
}
版权归属:
会飞的大象
许可协议:
本文使用《署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0)》协议授权
评论区