Ответ 1
Следующий код показывает, как создать SSLContext для HTTPS-сервера путем анализа файла PEM с несколькими записями, например нескольких сертификатов и одного RSA PRIVATE KEY
. Однако он неполный, потому что простая Java 8 не может проанализировать данные частного ключа RSA PKCS # 1. Поэтому кажется, что ваше желание сделать это без какой-либо библиотеки невозможно. Требуется, по крайней мере, BouncyCastle для разбора данных PKCS # 1 (а также может использоваться анализатор PEM BouncyCastle).
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;
}