This article will contain info on how to enable Mutual SSL in Spring Boot.
1. Prerequisites
- crt (or cer) and key file
- OpenSSL installed
- Keytool installed
2. Generate trust and keystore
We first need to generate a p12 truststore. This will house both the required certificates as well as the relevant key. Use the following command to generate the keystore containing the .crt and .key files:
openssl pkcs12 -export \
-in <.crt file> -inkey <.key file> \
-out truststore.p12
To make sure that the application can sign the HTTPS connection, we also need to add any root certificates. In my case I need to add the Dutch Government certificate which can be downloaded from http://cert.pkioverheid.nl/RootCA-G3.cer
keytool -import -alias rootCa_g3 -keystore truststore.p12 \
-file RootCA-G3.cer
3. Configure RestTemplate
Place the keystorefile in the resources folder in your Spring application (preferably in a somewhat logical place).
Add the file to your properties:
#trust store location
trust.store=classpath:truststore.p12
#trust store password
trust.store.password=<password>
Now we need to configure the RestTemplate bean in Spring. Use the following code example:
@Bean
RestTemplate restTemplate() throws Exception {
SSLContext sslContext = new SSLContextBuilder()
.loadKeyMaterial(
createKeyMaterial(trustStore, trustStorePassword),
trustStorePassword.toCharArray())
.loadTrustMaterial(trustStore.getURL(),
trustStorePassword.toCharArray())
.build();
SSLConnectionSocketFactory socketFactory =
new SSLConnectionSocketFactory(sslContext);
HttpClient httpClient = HttpClients.custom()
.setSSLSocketFactory(socketFactory)
.build();
HttpComponentsClientHttpRequestFactory factory =
new HttpComponentsClientHttpRequestFactory(httpClient);
return new RestTemplate(factory);
}
private KeyStore createKeyMaterial(Resource trustStore, String pwd)
throws IOException, KeyStoreException,
CertificateException, NoSuchAlgorithmException {
KeyStore keyStore = KeyStore.getInstance("PKCS12");
File key = trustStore.getFile();
try (InputStream in = new FileInputStream(key)) {
keyStore.load(in, pwd.toCharArray());
}
return keyStore;
}
4. Make request!
To make a request, just use the RestTemplate bean!
@RunWith(SpringRunner.class)
@SpringBootTest
public class MutialSslTestApplicationTests {
private static final String URL = "<URL>";
@Autowired
private RestTemplate restTemplate;
@Test
public void contextLoads() {
String s = restTemplate.getForObject(URL, String.class);
System.out.println(s);
}
}