Skip to content

Commit 1898a06

Browse files
committed
fix: using io.github.hakky54:ayza-for-pem to load KeyManager for PEM
1 parent 944fc1c commit 1898a06

File tree

2 files changed

+19
-74
lines changed

2 files changed

+19
-74
lines changed

pom.xml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,13 @@
167167
<artifactId>okhttp-brotli</artifactId>
168168
<version>4.12.0</version>
169169
</dependency>
170+
171+
<!--证书加载支持-->
172+
<dependency>
173+
<groupId>io.github.hakky54</groupId>
174+
<artifactId>ayza-for-pem</artifactId>
175+
<version>10.0.1</version>
176+
</dependency>
170177
</dependencies>
171178
<build>
172179
<plugins>

src/main/java/com/laker/postman/service/http/ssl/ClientCertificateLoader.java

Lines changed: 12 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,16 @@
11
package com.laker.postman.service.http.ssl;
22

3+
import cn.hutool.core.io.FileUtil;
4+
import cn.hutool.core.util.StrUtil;
35
import com.laker.postman.model.ClientCertificate;
46
import lombok.extern.slf4j.Slf4j;
7+
import nl.altindag.ssl.pem.util.PemUtils;
58

69
import javax.net.ssl.KeyManager;
710
import javax.net.ssl.KeyManagerFactory;
11+
import javax.net.ssl.X509ExtendedKeyManager;
812
import javax.net.ssl.X509KeyManager;
13+
import java.io.BufferedInputStream;
914
import java.io.FileInputStream;
1015
import java.io.IOException;
1116
import java.net.Socket;
@@ -70,82 +75,15 @@ private static KeyManager[] createKeyManagersFromPFX(ClientCertificate cert) thr
7075
* 从 PEM 文件创建 KeyManager
7176
*/
7277
private static KeyManager[] createKeyManagersFromPEM(ClientCertificate cert) throws Exception {
73-
// 加载证书
74-
X509Certificate certificate = loadCertificateFromPEM(cert.getCertPath());
78+
log.debug("Loaded PEM certificate from: {} and key from: {}", cert.getCertPath(), cert.getKeyPath());
79+
try (BufferedInputStream certInputStream = FileUtil.getInputStream(cert.getCertPath());
80+
BufferedInputStream keyInputStream = FileUtil.getInputStream(cert.getKeyPath())) {
7581

76-
// 加载私钥
77-
PrivateKey privateKey = loadPrivateKeyFromPEM(cert.getKeyPath(), cert.getKeyPassword());
82+
X509ExtendedKeyManager keyManager = StrUtil.isNotBlank(cert.getKeyPassword())
83+
? PemUtils.loadIdentityMaterial(certInputStream, keyInputStream, cert.getKeyPassword().toCharArray())
84+
: PemUtils.loadIdentityMaterial(certInputStream, keyInputStream);
7885

79-
// 创建 KeyStore 并添加证书和私钥
80-
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
81-
keyStore.load(null, null);
82-
83-
Certificate[] certChain = new Certificate[]{certificate};
84-
char[] keyPassword = cert.getKeyPassword() != null ?
85-
cert.getKeyPassword().toCharArray() : new char[0];
86-
87-
keyStore.setKeyEntry("client-cert", privateKey, keyPassword, certChain);
88-
89-
KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
90-
kmf.init(keyStore, keyPassword);
91-
92-
log.debug("Loaded PEM certificate from: {} and key from: {}",
93-
cert.getCertPath(), cert.getKeyPath());
94-
return kmf.getKeyManagers();
95-
}
96-
97-
/**
98-
* 从 PEM 文件加载 X509 证书
99-
*/
100-
private static X509Certificate loadCertificateFromPEM(String certPath) throws IOException, CertificateException {
101-
String content = new String(Files.readAllBytes(Paths.get(certPath)));
102-
content = content.replace("-----BEGIN CERTIFICATE-----", "")
103-
.replace("-----END CERTIFICATE-----", "")
104-
.replaceAll("\\s", "");
105-
106-
byte[] certBytes = Base64.getDecoder().decode(content);
107-
CertificateFactory cf = CertificateFactory.getInstance("X.509");
108-
return (X509Certificate) cf.generateCertificate(
109-
new java.io.ByteArrayInputStream(certBytes));
110-
}
111-
112-
/**
113-
* 从 PEM 文件加载私钥
114-
*/
115-
private static PrivateKey loadPrivateKeyFromPEM(String keyPath, String password)
116-
throws IOException, GeneralSecurityException {
117-
String content = new String(Files.readAllBytes(Paths.get(keyPath)));
118-
119-
// 检查是否是加密的私钥
120-
if (content.contains("ENCRYPTED")) {
121-
// 注意:password 参数预留用于未来支持加密私钥
122-
throw new IllegalArgumentException(
123-
"Encrypted PEM private keys are not supported yet. " +
124-
"Please use unencrypted PEM or convert to PFX/P12 format. " +
125-
"Password parameter: " + (password != null ? "provided" : "not provided"));
126-
}
127-
128-
// 移除 PEM 头尾和空白字符
129-
content = content.replaceAll("-----BEGIN.*PRIVATE KEY-----", "")
130-
.replaceAll("-----END.*PRIVATE KEY-----", "")
131-
.replaceAll("\\s", "");
132-
133-
byte[] keyBytes = Base64.getDecoder().decode(content);
134-
PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(keyBytes);
135-
136-
// 尝试 RSA
137-
try {
138-
KeyFactory kf = KeyFactory.getInstance("RSA");
139-
return kf.generatePrivate(spec);
140-
} catch (Exception e) {
141-
// 尝试 EC
142-
try {
143-
KeyFactory kf = KeyFactory.getInstance("EC");
144-
return kf.generatePrivate(spec);
145-
} catch (Exception e2) {
146-
throw new GeneralSecurityException(
147-
"Failed to load private key. Supported algorithms: RSA, EC", e);
148-
}
86+
return new KeyManager[]{keyManager};
14987
}
15088
}
15189

0 commit comments

Comments
 (0)