gpt4 book ai didi

java - 在 Java 中,仅使用 PEM 文件创建 SSLContext 的最简单方法是什么?

转载 作者:搜寻专家 更新时间:2023-10-30 20:54:27 25 4
gpt4 key购买 nike

我使用 LetsEncrypt 的 CertBot 免费生成 PEM 文件。在其他语言中,只需使用几行代码和 PEM/ key 文件即可轻松启动 HTTPS 服务器。到目前为止,我在 Java 中找到的解决方案过于复杂,我正在寻找更简单的解决方案。

  1. 我不想使用 java 的命令行“keytool”。我只想将我的 PEM/ key 文件拖放到我的 eclipse 中,然后使用 SSLContext 以编程方式启动 HTTPS 服务器。
  2. 我不想包含像 BouncyCaSTLe 这样的大量外部库。请参阅以下链接,了解使用 BouncyCaSTLe 的假定解决方案:How to build a SSLSocketFactory from PEM certificate and key without converting to keystore?

有更好/更简单的方法吗?

最佳答案

以下代码大体展示了如何通过解析具有多个条目的 PEM 文件为 HTTPS 服务器创建 SSLContext,例如几个证书和一个 RSA PRIVATE KEY。然而它是不完整的,因为纯 Java 8 无法解析 PKCS#1 RSA 私钥数据。因此,您似乎无法在没有任何图书馆的情况下做到这一点。至少需要用于解析 PKCS#1 数据的 BouncyCaSTLe(然后也可以使用 BouncyCaSTLe 的 PEM 解析器)。

private SSLContext createSslContext() throws Exception {
URL url = getClass().getResource("/a.pem");
InputStream in = url.openStream();
String pem = new String(in.readAllBytes(), StandardCharsets.UTF_8);
Pattern parse = Pattern.compile("(?m)(?s)^---*BEGIN ([^-]+)---*$([^-]+)^---*END[^-]+-+$");
Matcher m = parse.matcher(pem);
CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
Decoder decoder = Base64.getMimeDecoder();
List<Certificate> certList = new ArrayList<>(); // java.security.cert.Certificate

PrivateKey privateKey = null;

int start = 0;
while (m.find(start)) {
String type = m.group(1);
String base64Data = m.group(2);
byte[] data = decoder.decode(base64Data);
start += m.group(0).length();
type = type.toUpperCase();
if (type.contains("CERTIFICATE")) {
Certificate cert = certFactory.generateCertificate(new ByteArrayInputStream(data));
certList.add(cert);
} else if (type.contains("RSA PRIVATE KEY")) {
// TODO: load and parse PKCS1 data structure to get the RSA private key
privateKey = ...
} else {
System.err.println("Unsupported type: " + type);
}

}
if (privateKey == null)
throw new RuntimeException("RSA private key not found in PEM file");

char[] keyStorePassword = new char[0];

KeyStore keyStore = KeyStore.getInstance("JKS");
keyStore.load(null, null);

int count = 0;
for (Certificate cert : certList) {
keyStore.setCertificateEntry("cert" + count, cert);
count++;
}
Certificate[] chain = certList.toArray(new Certificate[certList.size()]);
keyStore.setKeyEntry("key", privateKey, keyStorePassword, chain);

TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
tmf.init(keyStore);
KeyManagerFactory kmf = KeyManagerFactory.getInstance("RSA");
kmf.init(keyStore, keyStorePassword);
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), new SecureRandom());
return sslContext;
}

关于java - 在 Java 中,仅使用 PEM 文件创建 SSLContext 的最简单方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50025086/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com