0

I am not very much familiar with ssl authentication but as I have need to do it now, I just googled as bit and found that below are some the steps to generate a client certificate and use it in java. Also I have written a sample Java program just to know whether the authentication in happening or not. But some it throws me a famous exception

sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target

Can anyone tell me where I am going wrong here? I just tried to keep the steps very simple.

On Client server(ip1): **

  • Step 1:

** I have generated a keystore on a client server

keytool -genkey -alias "clientalias" 
                        -keyalg RSA 
                        -keystore keystore.jks 
                        -dname "CN=client, OU=SDE, O=NC, L=HYD, S=TN, C=IN" 
                        -storepass password 
                        -keypass password

**

  • Step 2:

** I have created a certificate(.cer) file on the client server

keytool -export -alias "clientalias" 
                       -file client.cer 
                       -keystore keystore.jks 
                       -storepass password

**

  • Step 3:

** I have copied the cer file to the server host(ip2)

scp client.cer  user@ip2:/some/path/

On Server host(ip2):

I have imported the certificate generated on the client server and then imported in the cacerts file /u01/app/java/jdk1.8.0_291/jre/lib/security/cacerts

keytool -import -v -trustcacerts -alias clientalias 
                                              -file client.cer 
                                              -keystore /u01/app/java/jdk180_291/jre/lib/security/cacerts 
                                              -keypass changeit 
                                              -storepass changeit

Java source for testing SSL:

import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
import java.io.*;

public class SSLPoke {
    public static void main(String[] args) {
                if (args.length != 2) {
                        System.out.println("Usage: "+SSLPoke.class.getName()+" <host> <port>");
                        System.exit(1);
                }
                try {

                       System.setProperty("javax.net.ssl.TrustStore", "/some/path/keystore.jks");
                       System.setProperty("javax.net.ssl.TrustStorePassword", "password" );
                       System.setProperty("javax.net.ssl.keyStoreType", "JKS" );
                       System.setProperty("javax.net.debug", "ssl,trustmanager" );

                       SSLSocketFactory sslsocketfactory = (SSLSocketFactory) SSLSocketFactory.getDefault();
                       SSLSocket sslsocket = (SSLSocket) sslsocketfactory.createSocket(args[0], Integer.parseInt(args[1]));

                        InputStream in = sslsocket.getInputStream();
                        OutputStream out = sslsocket.getOutputStream();

                        // Write a test byte to get a reaction :)
                        out.write(1);

                        while (in.available() > 0) {
                                System.out.print(in.read());
                        }
                        System.out.println("Successfully connected");

                } catch (Exception exception) {
                        exception.printStackTrace();
                }
        }
}

Also in the debug output I could see the trust store presented has the certificate created by me.

Vijay
  • 65,327
  • 90
  • 227
  • 319
  • The truststore doesn't trust then generated certificate. You imported it into the JDK truststore, which you should not have done, and then used a different truststore, which is where you should have imported it to. – user207421 Jun 18 '21 at 01:34
  • You created a cert _for client authentication_. For client code like your version of SSLPoke to use such a cert, the file containing it must be configured as the client's _keystore_ (NOT the client's _truststore_ which is used to authenticate the _server's_ cert) AND the server must request client auth, which most don't; your javax.net.debug output will show whether the server sent a CertificateRequest message (and if so what was in it). Also properties are casesensitive so `TrustStore` is not the same as `trustStore`. – dave_thompson_085 Jun 18 '21 at 06:10

0 Answers0