diff --git a/src/main/java/com/qiumo/help/context/CertificateContextHolder.java b/src/main/java/com/qiumo/help/context/CertificateContextHolder.java index a265405..9e4ab55 100644 --- a/src/main/java/com/qiumo/help/context/CertificateContextHolder.java +++ b/src/main/java/com/qiumo/help/context/CertificateContextHolder.java @@ -95,6 +95,33 @@ public class CertificateContextHolder { /** 服务器子证书文件路径 */ private static final String SERVER_CHILD_CET_FILE_NAME = "external/certificate/server-child-ca.crt"; + /** 证书有效期(年) */ + private static final int CERTIFICATE_VALIDITY_YEARS = 100; + + /** RSA签名算法 */ + private static final String SIGNATURE_ALGORITHM = "SHA256withRSA"; + + /** BouncyCastle提供者标识 */ + private static final String BC_PROVIDER = "BC"; + + /** RSA加密算法标识 */ + private static final String RSA_ALGORITHM = "RSA"; + + /** 授权码签名CA的DN */ + private static final String CODE_CA_DN = "CN=JetProfile CA"; + + /** 许可证服务器CA的DN */ + private static final String LICENSE_SERVER_CA_DN = "CN=License Servers CA"; + + /** 应用程序主体DN */ + private static final String APP_SUBJECT_DN = "CN=QiuMo-Jetbrains-Help"; + + /** 许可证服务器域名 */ + private static final String LICENSE_SERVER_DOMAIN = "qiumo.lsrv.jetbrains.com"; + + /** 许可证服务器主体DN */ + private static final String LICENSE_SERVER_SUBJECT_DN = "CN=" + LICENSE_SERVER_DOMAIN; + // ==================== 静态文件对象 ==================== /** 授权码根密钥文件对象 */ @@ -308,7 +335,7 @@ public class CertificateContextHolder { private static KeyPair generateRSAKeyPair(int keySize) { try { log.debug("生成{}位RSA密钥对", keySize); - return SecureUtil.generateKeyPair("RSA", keySize); + return SecureUtil.generateKeyPair(RSA_ALGORITHM, keySize); } catch (Exception e) { throw new RuntimeException("RSA密钥对生成失败: " + keySize + "位", e); } @@ -324,14 +351,17 @@ public class CertificateContextHolder { private static void saveKeyPairToFiles(KeyPair keyPair, String privateKeyPath, String publicKeyPath) { try { // 保存私钥 - privateKeyFile = FileTools.getFileOrCreat(privateKeyPath); + File privateKeyFileObj = FileTools.getFileOrCreat(privateKeyPath); PemUtil.writePemObject("PRIVATE KEY", keyPair.getPrivate().getEncoded(), - FileUtil.getWriter(privateKeyFile, StandardCharsets.UTF_8, false)); + FileUtil.getWriter(privateKeyFileObj, StandardCharsets.UTF_8, false)); // 保存公钥 - publicKeyFile = FileTools.getFileOrCreat(publicKeyPath); + File publicKeyFileObj = FileTools.getFileOrCreat(publicKeyPath); PemUtil.writePemObject("PUBLIC KEY", keyPair.getPublic().getEncoded(), - FileUtil.getWriter(publicKeyFile, StandardCharsets.UTF_8, false)); + FileUtil.getWriter(publicKeyFileObj, StandardCharsets.UTF_8, false)); + + publicKeyFile = publicKeyFileObj; + privateKeyFile = privateKeyFileObj; log.debug("密钥对已保存: {} 和 {}", privateKeyPath, publicKeyPath); @@ -351,8 +381,8 @@ public class CertificateContextHolder { PublicKey publicKey4096 = keyPair.getPublic(); // 创建内容签名器 - ContentSigner signer = new JcaContentSignerBuilder("SHA256withRSA").build(privateKey4096); - JcaX509CertificateConverter certConverter = new JcaX509CertificateConverter().setProvider("BC"); + ContentSigner signer = new JcaContentSignerBuilder(SIGNATURE_ALGORITHM).build(privateKey4096); + JcaX509CertificateConverter certConverter = new JcaX509CertificateConverter().setProvider(BC_PROVIDER); // 生成授权码签名CA证书 Certificate codeCertificate = generateCodeCACertificate(publicKey4096, signer, certConverter); @@ -380,13 +410,13 @@ public class CertificateContextHolder { * @return 生成的授权码签名CA证书 */ private static Certificate generateCodeCACertificate(PublicKey publicKey, ContentSigner signer, - JcaX509CertificateConverter certConverter) throws Exception { + JcaX509CertificateConverter certConverter) throws Exception { JcaX509v3CertificateBuilder certificateBuilder = new JcaX509v3CertificateBuilder( - new X500Name("CN=JetProfile CA"), // 颁发者DN + new X500Name(CODE_CA_DN), // 颁发者DN BigInteger.valueOf(System.currentTimeMillis()), // 序列号 DateUtil.yesterday().toJdkDate(), // 生效日期(昨天,避免时钟偏差) - DateUtil.date().offset(DateField.YEAR, 100).toJdkDate(), // 过期日期 - new X500Name("CN=QiuMo-Jetbrains-Help"), // 主体DN + DateUtil.date().offset(DateField.YEAR, CERTIFICATE_VALIDITY_YEARS).toJdkDate(), // 过期日期 + new X500Name(APP_SUBJECT_DN), // 主体DN SubjectPublicKeyInfo.getInstance(publicKey.getEncoded())); // 公钥信息 return certConverter.getCertificate(certificateBuilder.build(signer)); @@ -401,13 +431,13 @@ public class CertificateContextHolder { * @return 生成的许可证服务器CA证书 */ private static Certificate generateServerCACertificate(PublicKey publicKey, ContentSigner signer, - JcaX509CertificateConverter certConverter) throws Exception { + JcaX509CertificateConverter certConverter) throws Exception { JcaX509v3CertificateBuilder serversCertBuilder = new JcaX509v3CertificateBuilder( - new X500Name("CN=License Servers CA"), // 颁发者DN + new X500Name(LICENSE_SERVER_CA_DN), // 颁发者DN BigInteger.valueOf(System.currentTimeMillis()), // 序列号 DateUtil.yesterday().toJdkDate(), // 生效日期 - DateUtil.date().offset(DateField.YEAR, 100).toJdkDate(), // 过期日期 - new X500Name("CN=QiuMo-Jetbrains-Help"), // 主体DN + DateUtil.date().offset(DateField.YEAR, CERTIFICATE_VALIDITY_YEARS).toJdkDate(), // 过期日期 + new X500Name(APP_SUBJECT_DN), // 主体DN SubjectPublicKeyInfo.getInstance(publicKey.getEncoded())); // 公钥信息 return certConverter.getCertificate(serversCertBuilder.build(signer)); @@ -431,13 +461,13 @@ public class CertificateContextHolder { * @return 生成的服务器子证书 */ private static Certificate generateServerChildCertificate(PublicKey publicKey4096, - ContentSigner signer, JcaX509CertificateConverter certConverter) throws Exception { + ContentSigner signer, JcaX509CertificateConverter certConverter) throws Exception { JcaX509v3CertificateBuilder childCertBuilder = new JcaX509v3CertificateBuilder( - new X500Name("CN=License Servers CA"), // 颁发者DN + new X500Name(LICENSE_SERVER_CA_DN), // 颁发者DN BigInteger.valueOf(System.currentTimeMillis()), // 序列号 DateUtil.yesterday().toJdkDate(), // 生效日期 - DateUtil.date().offset(DateField.YEAR, 100).toJdkDate(), // 过期日期 - new X500Name("CN=qiumo.lsrv.jetbrains.com"), // 主体DN(具体域名) + DateUtil.date().offset(DateField.YEAR, CERTIFICATE_VALIDITY_YEARS).toJdkDate(), // 过期日期 + new X500Name(LICENSE_SERVER_SUBJECT_DN), // 主体DN(具体域名) SubjectPublicKeyInfo.getInstance(publicKey4096.getEncoded())); // 公钥信息 // 添加证书扩展 @@ -464,7 +494,7 @@ public class CertificateContextHolder { // 2. 主体备用名称:DNS域名 GeneralNamesBuilder generalNamesBuilder = new GeneralNamesBuilder(); - GeneralName dnsName = new GeneralName(GeneralName.dNSName, "qiumo.lsrv.jetbrains.com"); + GeneralName dnsName = new GeneralName(GeneralName.dNSName, LICENSE_SERVER_SUBJECT_DN); generalNamesBuilder.addName(dnsName); GeneralNames generalNames = generalNamesBuilder.build(); certBuilder.addExtension(Extension.subjectAlternativeName, false, generalNames); @@ -495,7 +525,7 @@ public class CertificateContextHolder { * @param childCertificate 服务器子证书 */ private static void saveCertificatesToFiles(Certificate codeCertificate, Certificate serverCertificate, - Certificate childCertificate) throws Exception { + Certificate childCertificate) throws Exception { // 创建证书文件对象 codeCrtFile = FileTools.getFileOrCreat(CODE_CET_FILE_NAME); serverCrtFile = FileTools.getFileOrCreat(SERVER_CET_FILE_NAME);