Skip to content

Instantly share code, notes, and snippets.

@hurelhuyag
Last active April 11, 2022 09:24
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hurelhuyag/8d327452acd8eff815d24cc4f4f83bb0 to your computer and use it in GitHub Desktop.
Save hurelhuyag/8d327452acd8eff815d24cc4f4f83bb0 to your computer and use it in GitHub Desktop.
Two-Way SSL or Mutual SSL or Mutual Authentication Java Demo
#!/bin/bash
## convert pem key file to p12 format
openssl pkcs12 -export -inkey key.key -in truststore.crt -out key.p12
## create empty JKS truststore
keytool -genkey -keyalg RSA -alias 1 -keystore truststore.jks
keytool -delete -alias 1 -keystore truststore.jks
keytool -import -v -trustcacerts -alias 1 -file truststore.crt -keystore truststore.jks
import javax.net.ssl.*;
import java.io.*;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.security.*;
import java.util.Base64;
public class HttpsUrlConnectionExample {
/**
* further reading:
* - https://docs.oracle.com/javase/8/docs/technotes/guides/security/jsse/JSSERefGuide.html#ex1
* - https://docs.oracle.com/en/java/javase/18/security/java-secure-socket-extension-jsse-reference-guide.html
*/
public static SSLContext createSSLContext() throws IOException, GeneralSecurityException {
var ksKeys = KeyStore.getInstance(new File("key.p12"), "key_pass".toCharArray());
var ksTrust = KeyStore.getInstance(new File("truststore.jks"), "store_pass".toCharArray());
// KeyManagers decide which key material to use
var kmf = KeyManagerFactory.getInstance("PKIX");
kmf.init(ksKeys, "key_pass".toCharArray());
// TrustManagers decide whether to allow connections
var tmf = TrustManagerFactory.getInstance("PKIX");
tmf.init(ksTrust);
// Get an instance of SSLContext for TLS protocols
var sslContext = SSLContext.getInstance("TLS");
sslContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
return sslContext;
}
public static void main(String[] args) throws Exception {
//System.setProperty("javax.net.debug", "all");
var sslContext = createSSLContext();
var conn = (HttpsURLConnection) new URL("https://1.2.3.4:8080/").openConnection();
conn.setSSLSocketFactory(sslContext.getSocketFactory());
conn.setHostnameVerifier((hostname, session) -> true);
conn.setRequestMethod("GET");
conn.setDoOutput(true);
InputStream is;
if (conn.getResponseCode() < HttpsURLConnection.HTTP_BAD_REQUEST) {
is = conn.getInputStream();
} else {
/* error from server */
is = conn.getErrorStream();
}
try (var in = new BufferedReader(new InputStreamReader(is, StandardCharsets.UTF_8))) {
String inputLine;
while ((inputLine = in.readLine()) != null) {
System.out.println(inputLine);
}
}
}
}
import org.springframework.web.client.RestTemplate;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManagerFactory;
import java.io.File;
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.security.KeyStore;
/**
* Spring RestTemplate demo
*/
public class RestTemplateExample {
public static void main(String[] args) throws GeneralSecurityException, IOException {
RestTemplate restTemplate = new RestTemplate(new TwoWaySSLClientHttpRequestFactory(createSSLContext()));
var result = restTemplate.getForObject("https://1.2.3.4:8080/", ResponseType.class);
System.out.println(result);
}
}
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.Proxy;
import java.net.URL;
public class TwoWaySSLClientHttpRequestFactory extends SimpleClientHttpRequestFactory {
private final SSLContext sslContext;
public TwoWaySSLClientHttpRequestFactory(SSLContext sslContext) {
this.sslContext = sslContext;
}
@Override
protected HttpURLConnection openConnection(URL url, Proxy proxy) throws IOException {
var conn = (HttpsURLConnection) super.openConnection(url, proxy);
conn.setSSLSocketFactory(sslContext.getSocketFactory());
conn.setHostnameVerifier((hostname, session) -> true);
return conn;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment