证书问题已解决

This commit is contained in:
M0914
2025-09-12 11:16:01 +08:00
parent 7777115c17
commit 282d667dd0
@@ -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);
@@ -382,11 +412,11 @@ public class CertificateContextHolder {
private static Certificate generateCodeCACertificate(PublicKey publicKey, ContentSigner signer,
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));
@@ -403,11 +433,11 @@ public class CertificateContextHolder {
private static Certificate generateServerCACertificate(PublicKey publicKey, ContentSigner signer,
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));
@@ -433,11 +463,11 @@ public class CertificateContextHolder {
private static Certificate generateServerChildCertificate(PublicKey publicKey4096,
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);