javasslssl-certificatekeystoresslcontext

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


I need to create a SSLContext for a Cloudflare Origin Certificate.

A certificate and private key are provided. The certificate is provided in the following formats:

The private key is provided in a single format, whose name is not specified. Here is an example:

-----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-----

In Java 11, how do I create a KeyManager[] that I can then use to create a SSLContext in the following way?

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

Solution

  • Convert the PEM certificate and private key to PKCS12:

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

    Then, to create the 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);
    

    To generate a self-signed certificate for local development, use:

    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")