From 95bd0604b6fea615b59dbfcbc1d0784e7c232e3b Mon Sep 17 00:00:00 2001 From: cheney Date: Wed, 29 Apr 2026 17:29:49 +0800 Subject: [PATCH] =?UTF-8?q?=E8=B0=83=E6=95=B4=E8=AF=81=E4=B9=A6=E6=8E=A5?= =?UTF-8?q?=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../tms/modules/cert/enums/CertUsage.java | 16 ++++ .../repository/CertificateRepository.java | 2 + .../impl/CertificateRepositoryImpl.java | 26 +++--- .../tms/modules/cert/support/CertUtil.java | 84 +++++++++++++++++++ .../openapi/service/impl/OpenApiService.java | 6 +- 5 files changed, 120 insertions(+), 14 deletions(-) create mode 100644 src/main/java/com/cisd/tms/modules/cert/enums/CertUsage.java create mode 100644 src/main/java/com/cisd/tms/modules/cert/support/CertUtil.java diff --git a/src/main/java/com/cisd/tms/modules/cert/enums/CertUsage.java b/src/main/java/com/cisd/tms/modules/cert/enums/CertUsage.java new file mode 100644 index 0000000..b9caf7e --- /dev/null +++ b/src/main/java/com/cisd/tms/modules/cert/enums/CertUsage.java @@ -0,0 +1,16 @@ +package com.cisd.tms.modules.cert.enums; + +/** + * 证书用途 + */ +public enum CertUsage { + digitalSignature, + nonRepudiation, + keyEncipherment, + dataEncipherment, + keyAgreement, + keyCertSign, + cRLSign, + encipherOnly, + decipherOnly +} diff --git a/src/main/java/com/cisd/tms/modules/cert/repository/CertificateRepository.java b/src/main/java/com/cisd/tms/modules/cert/repository/CertificateRepository.java index 501a4cb..6be1b0d 100644 --- a/src/main/java/com/cisd/tms/modules/cert/repository/CertificateRepository.java +++ b/src/main/java/com/cisd/tms/modules/cert/repository/CertificateRepository.java @@ -10,8 +10,10 @@ public interface CertificateRepository { void deleteById(Long id); Optional findById(Long id); Optional findByFingerprint(String fingerprint); + Optional findBySubjectDn(String subjectDn); Optional findByIssuerDnAndSerialNumber(String issuerDn, String serialNumber); boolean existsEntityCertByEntityId(Long entityId); long countByIssuerDn(String issuerDn); Page page(CertificateListRequest request); } + diff --git a/src/main/java/com/cisd/tms/modules/cert/repository/impl/CertificateRepositoryImpl.java b/src/main/java/com/cisd/tms/modules/cert/repository/impl/CertificateRepositoryImpl.java index 47ad9ae..e9e1aed 100644 --- a/src/main/java/com/cisd/tms/modules/cert/repository/impl/CertificateRepositoryImpl.java +++ b/src/main/java/com/cisd/tms/modules/cert/repository/impl/CertificateRepositoryImpl.java @@ -49,6 +49,15 @@ public class CertificateRepositoryImpl implements CertificateRepository { return Optional.ofNullable(mapper.selectOne(wrapper)); } + @Override + public Optional findBySubjectDn(String subjectDn) { + LambdaQueryWrapper wrapper = new LambdaQueryWrapper() + .eq(CertificateEntity::getSubjectDn, subjectDn) + .orderByDesc(CertificateEntity::getImportTime) + .last("LIMIT 1"); + return Optional.ofNullable(mapper.selectOne(wrapper)); + } + @Override public Optional findByIssuerDnAndSerialNumber(String issuerDn, String serialNumber) { LambdaQueryWrapper wrapper = new LambdaQueryWrapper() @@ -75,20 +84,12 @@ public class CertificateRepositoryImpl implements CertificateRepository { @Override public Page page(CertificateListRequest request) { LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); - if (StringUtils.hasText(request.getOrgCode())) { - wrapper.apply( - "entity_id IN (SELECT id FROM t_key_entity WHERE org_code LIKE CONCAT('%', {0}, '%'))", - request.getOrgCode() - ); - } - if (StringUtils.hasText(request.getAlgoType())) { - wrapper.eq(CertificateEntity::getAlgoType, request.getAlgoType().toUpperCase()); - } if (StringUtils.hasText(request.getCertType())) { - wrapper.eq(CertificateEntity::getCertType, request.getCertType().toUpperCase()); + wrapper.eq(CertificateEntity::getCertType, request.getCertType()); } - if (StringUtils.hasText(request.getSubject())) { - wrapper.like(CertificateEntity::getSubjectDn, request.getSubject()); + if (StringUtils.hasText(request.getKeyword())) { + wrapper.and(w -> w.like(CertificateEntity::getSubjectDn, request.getKeyword()) + .or().like(CertificateEntity::getIssuerDn, request.getKeyword())); } wrapper.orderByDesc(CertificateEntity::getImportTime); long total = mapper.selectCount(wrapper); @@ -100,3 +101,4 @@ public class CertificateRepositoryImpl implements CertificateRepository { return page; } } + diff --git a/src/main/java/com/cisd/tms/modules/cert/support/CertUtil.java b/src/main/java/com/cisd/tms/modules/cert/support/CertUtil.java new file mode 100644 index 0000000..f8cb5f3 --- /dev/null +++ b/src/main/java/com/cisd/tms/modules/cert/support/CertUtil.java @@ -0,0 +1,84 @@ +package com.cisd.tms.modules.cert.support; + + +import com.cisd.tms.modules.cert.enums.CertUsage; +import lombok.SneakyThrows; +import org.bouncycastle.jce.provider.BouncyCastleProvider; +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.security.NoSuchProviderException; +import java.security.Security; +import java.security.cert.CertificateEncodingException; +import java.security.cert.CertificateException; +import java.security.cert.CertificateFactory; +import java.security.cert.X509Certificate; +import java.util.HashSet; +import java.util.Set; +import java.util.Base64; + + +public class CertUtil { + static { + Security.addProvider(new BouncyCastleProvider()); + } + + @SneakyThrows + public static X509Certificate convertToX509Cert(String certificateString) { +// X509Certificate certificate = null; +// CertificateFactory cf = null; +// try { +// if (certificateString != null && !certificateString.trim().isEmpty()) { +// certificateString = certificateString.replace("-----BEGIN CERTIFICATE-----\n", "") +// .replace("-----END CERTIFICATE-----", ""); // NEED FOR PEM FORMAT CERT STRING +// byte[] certificateData = Base64.decode(certificateString); +// cf = CertificateFactory.getInstance("X509"); +// certificate = (X509Certificate) cf.generateCertificate(new ByteArrayInputStream(certificateData)); +// } +// } catch (CertificateException e) { +// throw new CertificateException(e); +// } +// return certificate; + CertificateFactory CF = CertificateFactory.getInstance("X.509", "BC"); // 从证书工厂中获取X.509的单例类 + return (X509Certificate) CF.generateCertificate(new ByteArrayInputStream(certificateString.getBytes())); // 将文件流的证书转化为证书类 + } + + public static String convertToPem(String cert) throws CertificateEncodingException { + + String cert_begin = "-----BEGIN CERTIFICATE-----\n"; + String end_cert = "\n-----END CERTIFICATE-----"; + + byte[] derCert = cert.getBytes(); + String pemCertPre = Base64.getMimeEncoder().encodeToString(derCert); + String pemCert = cert_begin + pemCertPre + end_cert; + return pemCert; + } + + + public static boolean certUsageCheck(String cert , CertUsage... us ) throws CertificateException, NoSuchProviderException { + if ( null == us || us.length == 0) { + return true; + } + + X509Certificate certificate = convertToX509Cert(cert); + boolean[] usage = certificate.getKeyUsage(); + + if ( null == usage ) { + return false; + } + + boolean checkRet = true; + Set uset = new HashSet(); + for ( CertUsage u : us ) { + uset.add( u.ordinal() ); + } + + for ( int i = 0; i < usage.length; i++ ) { + if ( usage[ i ] ) { + checkRet &= uset.contains( i ); + } + } + + return checkRet; + } + +} diff --git a/src/main/java/com/cisd/tms/modules/openapi/service/impl/OpenApiService.java b/src/main/java/com/cisd/tms/modules/openapi/service/impl/OpenApiService.java index 39deabc..0ace31b 100644 --- a/src/main/java/com/cisd/tms/modules/openapi/service/impl/OpenApiService.java +++ b/src/main/java/com/cisd/tms/modules/openapi/service/impl/OpenApiService.java @@ -1,6 +1,8 @@ package com.cisd.tms.modules.openapi.service.impl; import com.cisd.tms.integration.crypto.pcie.service.JnaPcieCryptoService; +import com.cisd.tms.modules.cert.repository.CertificateRepository; +import com.cisd.tms.modules.cert.service.CertificateService; import com.cisd.tms.modules.openapi.service.IOpenApiService; import com.cisd.tms.modules.openapi.service.dto.GenericCertificate; import com.sun.jna.Pointer; @@ -22,7 +24,7 @@ import java.security.cert.X509Certificate; public class OpenApiService implements IOpenApiService { private JnaPcieCryptoService sdf; - + private final CertificateService certificateService; @Override public String rawSign(byte[] origBytes, String dn) { @@ -31,7 +33,7 @@ public class OpenApiService implements IOpenApiService { int keyIndex = 0; // 获取证书和公钥 - X509Certificate cert = certManager.getCertificate(dn); + X509Certificate cert = certificateService.getBySubjectDn(dn); if (cert == null) { throw new RuntimeException("Certificate not found for DN: " + dn); }