how to write java client and server applications that uses mutual ssl authentication between them?

后端 未结 2 490
盖世英雄少女心
盖世英雄少女心 2021-02-11 10:14

I\'m building two java applications which have to communicate using SSL two way authentication, I used instructions from here to create client and server certificates.
then

相关标签:
2条回答
  • 2021-02-11 10:49

    after spending a long time to make this work, the solution is as follows:
    first when setting the properties using System.put("key", "value") I noticed after many tries it is not setting the KeyStore value it is does not appear in the ssl log , also tried to set the properties as parameters in the tomcat configuration using -Djavax.net.ssl.keyStore="" this also didn't work.
    so I read the KeyStore from an InputStream like this:

        KeyStore keystore = KeyStore.getInstance(KeyStore.getDefaultType());
        FileInputStream io = new FileInputStream("path/to/jks/file.jks");
        try{
            keystore.load(io, "pass".toCharArray());
        } finally {
            io.close();
        }
    

    and use the same previous code to read the TrustStore like :

        KeyStore trustStore= KeyStore.getInstance(KeyStore.getDefaultType());
        FileInputStream stream = new FileInputStream("path/to/truststore/file.jks");
        try{
            keystore.load(stream, "trusted".toCharArray());
        } finally {
            stream.close();
        }
    

    after that define the SSLContext :

    SSLContext sslcontext = SSLContexts.custom()
                .loadKeyMaterial(keystore, "keyPassword".toCharArray())
                .loadTrustMaterial(truststore, new TrustSelfSignedStrategy())
                .build();  
    

    loadKeyMaterial used to load the keyStore it takes the password of your privateKey "keyPassword" as a parameter, so you must protect the private key using a password, when I tried to use a plain private key not encrypted "protected" with a password, I get exception which says: java.security.UnrecoverableKeyException: Cannot recover key, by default this is the same as the keystore password unless you changed it.
    then create the SSLConnectionSocketFactory and pass it as a parameter to the HttpClient .. this worked for me :)

    0 讨论(0)
  • 2021-02-11 11:12

    For anyone looking to implement 2 way mutual auth, following code worked perfectly for me.

        FileInputStream keystoreInputStream = null;
        FileInputStream truststoreInputStream = null;
        try {
    
            KeyStore keystore = KeyStore.getInstance(KeyStore.getDefaultType());
            keystoreInputStream = new FileInputStream("C:\\Users\\Aman\\STSProj\\AppSecurity\\clientkeystore.p12");
            keystore.load(keystoreInputStream, "client".toCharArray());
    
            keystoreInputStream.close();
    
            KeyStore trustore = KeyStore.getInstance(KeyStore.getDefaultType());
            truststoreInputStream = new FileInputStream("C:\\Users\\Aman\\STSProj\\AppSecurity\\clienttruststore.p12");
            trustore.load(truststoreInputStream, "client".toCharArray());
    
            SSLContext sslcontext = SSLContexts.custom().useProtocol("TLS")
                    .loadKeyMaterial(keystore, "client".toCharArray())
                    .loadTrustMaterial(trustore, null).build();
    
            HostnameVerifier hostnameverifier = null;
    
            SSLConnectionSocketFactory sslSocketFactory = new SSLConnectionSocketFactory(sslcontext,
                    null, null, hostnameverifier);
    
            CloseableHttpClient httpClient = HttpClients.custom().setSSLSocketFactory(sslSocketFactory).build();
    
            HttpsURLConnection.setDefaultSSLSocketFactory(sslcontext.getSocketFactory());
            HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory();
    
            requestFactory.setHttpClient(httpClient);
    
            RestTemplate restTemp = new RestTemplate(requestFactory);
    
            String greetings = restTemp
                    .getForObject("https://localhost:8443/SecureAppServer/test/security/hello/aman123", String.class);
    
            System.out.println("Received greetings from secured server ---> " + greetings);
    
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    
        finally {
            if (keystoreInputStream != null) {
                try {
                    keystoreInputStream.close();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            if (truststoreInputStream != null) {
                try {
                    truststoreInputStream.close();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
    
        }
    
    0 讨论(0)
提交回复
热议问题