Search code examples
javasslresttemplatepublic-key

How to obtain public key from an SSL connection


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?


Solution

  • 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.