如何从 PEM/PKCS7/DER 和私钥中的任一个创建 SSLContext?

How to create SSLContext from either of PEM/PKCS7/DER and private key?

我需要为 Cloudflare Origin 证书创建 SSLContext

提供证书和私钥。证书以下列格式提供:

私钥以单一格式提供,未指定名称。这是一个例子:

-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDKmiJFzrd/3y5S
uKGStmnyUdJKNzJEtgeoyZ6M+S4aFohyC6xM5wDvpWiXtzg1zppUCS2z6LaJRP1N
JlGE3JqolPXnl8hA5sqqD0ytgWKF9/5VRhoqjUayIQ+p593PBbg41Wc0N6ZavhLF
Lf/eIzKPQpsVQnzSMAUZXbwBCPNql9t3flZvmKveBuHD8ZaCjXvHaekOowneVPnM
D8XSlLoAbCAtAZmX6eLl2QxbmXjczsiNMHRFC0GO6sf43rq9bE7x3K3TzMv/EM+v
0VLR/WL9UadqC8+P2cfzrg5aAqsQFi4q3sUI5UwWrfPFvff30ZQSvHxWSqEFdVY0
uoW51ybHAgMBAAECggEABpPXIFcOuWBghkpSNzYkMxFu91PawO+mngHgW4lMyDIK
afwbsuoeVf6+ajaGOlD5IlijRYpSQBtKR0fthkJh5Fk5sTQfSeQe7kMi5SXPMgmU
FeakZinsrU8feA+msYLpBodUcMCMbmO/WOweY3LXFbQ+3q4oPpaqg7akVOWafs+y
emGBOA57kNu7/AerTZ5ydQZBbGDAxR+Vmgpd2BiSneeTHWFLHqC6xRXw904x+HTz
rOO7VJOoA7cAdYlMzrOvgurqjb0ba+wdKfHgbCIos7nj3/YfVNlFxr2IkmnXauLC
O6KaIydQ2rdN5bPdpiHx3WeyYroF2ti9VmK7gz3gGQKBgQD060UuIrNeYxE8yEkC
dJmGRtn9cUhtbVinvWVKBaahgSjfpNmmcuO1FknygIbSIUuP1ZkNVIPeAsrQt3EN
RU/QNglCAibBqxKY0CwvsroN/5e07l65zSWSSXcWl10gwySSz4Er1sNSF45GGV+h
zoJEtc5cp+m2RauSNzjwrmEdvQKBgQDTxLxGEnTPJNCQmOCv+V5FstmpmnHvb8en
VCykp0zSX6K+T7eXY+3oILqwyXyeoflcB6zfbC3MyEhfTrFLxPnwCtMLKeI4kUBh
OBM5vbGvUymIDuhTxMwJtOLJZ1B+n00n4gXprc6N007uKe4yTmrIhdn5sH7EOPVr
YT4in7p00wKBgQCeZrNdfU/o0cXKO/cMQYExmQ1Pnz6qlzfpdNLXpwP4HGLlEec6
gb/H1NyKnJmVubb3FbxhJLIMml21046oeJWAIhKmwGF0jEIA11Jcnwk6GH5zpF9b
Z9TO4fjFgavXjp5O3Sm7wrCcnWOE7tAtBDS4X6VRw7+iBTlL3a9T6lQhOQKBgFSj
D6Bt5fOYQidYgoyyfMQcjDPl/11z7nbpBIK2PtTh1jh7weOm08Hvus3HaaA5GmF2
y9fr844iChLVb7TZwA75NIoErl5vZyyz7bMpJqfs8+9mDeLVB7tlaTKXsSs6Xerv
we84QRKb/rLfXU0L3E/Sd2D88l1YanYFQoEyF6JzAoGADBtkMM9pF7eyLqBey1zd
NKxSa3hNikeg6OVG4Lj/sEH6vXjvkz/dCBkR5YSMl0EPGBqh1YC+zqbnDrgth7sQ
n3IfJ2wZ3mgfjriq5RCNqA8+Dv2WpcdgqN1W7s2WV88hQXTl8TsqUyIDl4PWrOHV
3DjkEpNcjyFspPaidOGrDfw=
-----END PRIVATE KEY-----

在 Java 11 中,我如何创建一个 KeyManager[] 然后我可以使用它以下列方式创建 SSLContext

KeyManager[] keyManagers = ...
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(keyManagers, null, null);

将 PEM 证书和私钥转换为 PKCS12:

openssl pkcs12 -export -out localhost.p12 -inkey localhost.key -in localhost.crt

然后,创建 SSLContext:

char[] password = ...

KeyStore keyStore = KeyStore.getInstance("PKCS12");
try (InputStream stream = ...) {
    keyStore.load(stream, password);
}

KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
keyManagerFactory.init(keyStore, password);

TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
trustManagerFactory.init(keyStore);

SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(keyManagerFactory.getKeyManagers(), trustManagerFactory.getTrustManagers(), null);

要为本地开发生成自签名证书,请使用:

openssl req -x509 -out localhost.crt -keyout localhost.key -newkey rsa:2048 -days 360 -nodes -sha256 -subj '/CN=localhost' -extensions EXT -config <( printf "[dn]\nCN=localhost\n[req]\ndistinguished_name = dn\n[EXT]\nsubjectAltName=DNS:localhost\nkeyUsage=digitalSignature\nextendedKeyUsage=serverAuth")