I have a REST service that I access via https. The parameters to the service include clear-text passwords which, at TRACE level logging appear in log files. To avoid inadvertent logging of these details I want to encrypt the passwords before sending, the obvious way (to me, at least) to do this being to use the public key of the https connection.
I don't want to disable the logging because the detail is sometimes useful and it would be very simple to inadvertently re-enable it.
I'm using Spring RestTemplate.
How do I get hold of the public key?
The way I have solved this is by making a HttpsURLConnection connection to the server.
KeyStore keyStore = loadKeystore(keystoreFilename, keystorePassword);
KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
kmf.init(keyStore, keystorePassword.toCharArray());
KeyStore trustStore = loadKeystore(truststoreFilename, truststorePassword);
TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
tmf.init(trustStore);
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(keyManagers, trustManagers, new java.security.SecureRandom());
URL destinationURL = new URL(origin);
HttpsURLConnection conn = (HttpsURLConnection) destinationURL.openConnection();
conn.setSSLSocketFactory(sslContext.getSocketFactory());
conn.connect();
return conn.getServerCertificates();
private KeyStore loadKeystore(String keyStoreFilename, String keyStorePassword) {
try {
final KeyStore trustStore = KeyStore.getInstance("JKS");
final InputStream is = new FileInputStream(keyStoreFilename);
trustStore.load(is, keyStorePassword.toCharArray());
return trustStore;
} catch (Exception ex) {
throw new MyException(ex);
}
}
This returns an array of certificates, the first element being the peer's certificate from which the public key can be obtained.