Java’s crypto APIs are flexible and powerful. But just awful to use. There are too many contexts, managers, factories, and providers. Want a certificate? Take your pick!
- java.security.Certificate
- java.security.cert.Certificate
- java.security.cert.X509Certificate
- javax.security.cert.Certificate
- javax.security.cert.X509Certificate
Gross.
Suppose you want to replace the host platform’s (scary) set of trusted certificate authorities with your own trimmed down set. This happens if you want to do HTTPS without paying a certificate authority each time your configuration changes. (You’d use certificate pinning if you wanted to avoid trusting all certificate authorities).
Most of the online advice I've seen suggests that you need Bouncy Castle and/or keytool
to first load the PEM files into a JKS
or BKS
keystore, which you then use to build an SSLContext
. That's annoying because it adds another opaque binary file to an already confusing process.
Fortunately, you can skip that step and read the PEMs directly. Hidden in plain sight within the certificate APIs is a mechanism to build an SSL socket factory from a PEM file like this one:
-----BEGIN CERTIFICATE-----
MIIFVTCCBD2gAwIBAgIRAKgHBM+t9Yx3v9G9tGZECWkwDQYJKoZIhvcNAQELBQAw
b21haW4gQ29udHJvbCBWYWxpZGF0ZWQxFDASBgNVBAsTC1Bvc2l0aXZlU1NMMRkw
FwYDVQQDExBwdWJsaWNvYmplY3QuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
oqEld6bOSoMlYavj9GCBSNIx2+mGS0Tg6A==
-----END CERTIFICATE-----
OkHttp's CustomTrust example has the goods on how to go from PEM to SSLContext
and SSLSocketFactory
and happy HTTPS.