I'm looking to use the new HttpClient provided in java 11. It's not clear how to do mutual TLS (2 way auth, where both client and server present a certificate.)
Could someone provide an example of mutual TLS with HttpClient?
I'm looking to use the new HttpClient provided in java 11. It's not clear how to do mutual TLS (2 way auth, where both client and server present a certificate.)
Could someone provide an example of mutual TLS with HttpClient?
Figured it out. Create an HttpClient, then pass in SSLContext and SSLParameters objects.
Load cert/key into SSLContext:
// cert+key data. assuming X509 pem format
final byte[] publicData = your_cert_data; // -----BEGIN CERTIFICATE----- ...
final byte[] privateData = your_key_data; // -----BEGIN PRIVATE KEY----- ...
// parse certificate
final CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
final Collection<? extends Certificate> chain = certificateFactory.generateCertificates(
new ByteArrayInputStream(publicData));
LOG.info("Successfully loaded the client cert certificate chain {}", String.join(" -> ", chain
.stream()
.map(certificate -> {
if (certificate instanceof X509Certificate) {
final X509Certificate x509Cert = (X509Certificate) certificate;
return x509Cert.getSubjectDN().toString();
} else {
return certificate.getType();
}
}).collect(Collectors.toList())));
// parse key
final Key key = KeyFactory.getInstance("RSA").generatePrivate(new PKCS8EncodedKeySpec(privateData));
// place cert+key into KeyStore
KeyStore clientKeyStore = KeyStore.getInstance("jks");
final char[] pwdChars = KEYSTORE_PASSWORD.toCharArray(); // use a random string, like from java.security.SecureRandom
clientKeyStore.load(null, null);
clientKeyStore.setKeyEntry(YOUR_SERVICE_NAME, key, pwdChars, chain.toArray(new Certificate[0]));
// initialize KeyManagerFactory
KeyManagerFactory keyMgrFactory = KeyManagerFactory.getInstance("SunX509");
keyMgrFactory.init(clientKeyStore, pwdChars);
// populate SSLContext with key manager
SSLContext sslCtx = SSLContext.getInstance("TLSv1.2");
sslCtx.init(keyMgrFactory.getKeyManagers(), null, null);
Create ssl parameters, set needClientAuth to true:
SSLParameters sslParam = new SSLParameters();
sslParam.setNeedClientAuth(true);
finally, create the HttpClient:
HttpClient client = HttpClient.newBuilder()
.sslContext(sslCtx)
.sslParameters(sslParam)
.build();