1
votes

I want to create SSL connection. I created keystore. and trying to use x509.

 final KeyManagerFactory kmf = KeyManagerFactory.getInstance("X509");

but I am getting below exception on console after running.

java.security.NoSuchAlgorithmException: X509 KeyManagerFactory not available at sun.security.jca.GetInstance.getInstance(Unknown Source) at javax.net.ssl.KeyManagerFactory.getInstance(Unknown Source) SSLContext sc = SSLContext.getInstance(connectionType); final char[] keyPassPhrase = "changeit".toCharArray(); //String [] array = Security.getProviders(); final KeyStore ks = KeyStore.getInstance("jks");

        ks.load(new FileInputStream("ClientKeyStore"), keyPassPhrase);
        provider();
        final KeyManagerFactory kmf = KeyManagerFactory.getInstance("X509"); // this line is problem

        // SunX509 : supporting only: [TLSv1, TLSv1.1, TLSv1.2]
        kmf.init(ks, keyPassPhrase);

        sc.init(kmf.getKeyManagers(), new TrustManager[] {
                new X509TrustManager(){
                    public java.security.cert.X509Certificate[] getAcceptedIssuers() {
                        return null;
                    }
                    @Override
                    public void checkClientTrusted(X509Certificate[] arg0, String arg1)
                            throws CertificateException {

                    }
                    public void checkServerTrusted(X509Certificate[] arg0, String arg1)
                            throws CertificateException {
                    }
                }
        },new SecureRandom());
        SSLSocketFactory factory = sc.getSocketFactory();
        SSLSocket socket=null;
        try{
            //socket = (SSLSocket) factory.createSocket("XXXX",xxxx);/
            socket = (SSLSocket) factory.createSocket(ipAddress, Integer.parseInt(ports[portIndex]));

            //convert to array
            String[] cipherSelectedArray;
            if(isSupported == 1 ) {
                cipherSelectedArray = new String[] {msupportedcipherList.get(cipherIndex).trim()};
            }
            else {
                cipherSelectedArray = new String[] {mnotSupportedcipherList.get(cipherIndex).trim()};
            }

            String []mselectedSSLOrTLSVersionArrray = new String[] {mselectedSSLOrTLSVersion};   // if passing these --> getting connection timeout

            socket.setEnabledProtocols(mselectedSSLOrTLSVersionArrray);
            socket.setEnabledCipherSuites(cipherSelectedArray);
            for(int i = 0; i<cipherSelectedArray.length ; i++) {
                //System.out.println("ciphers are :" +  cipherSelectedArray[i]);
            }


            socket.setSoTimeout(15000);

            socket.addHandshakeCompletedListener(new HandshakeCompletedListener() {

                @Override
                public void handshakeCompleted(HandshakeCompletedEvent event) {
                    ////System.out.println("completed");

                }
            });



            socket.startHandshake(); //handshake                                            as "SunX509" does not support SSL. I need to create above one. Can someone help.   And also with "SunX509" i am getting                                              java.lang.IllegalArgumentException: Cannot support TLS_RSA_WITH_AES_256_CBC_SHA with currently installed providers problem with some ciphers. please help
3

3 Answers

7
votes

The parameter you are using X509 is not recognized by the algorithm provider.

As described getInstance(String algorithm) the reason is clear.

NoSuchAlgorithmException - if no Provider supports a KeyManagerFactorySpi implementation for the specified algorithm.

The standard algorithms are described here

I guess they support PKIX, SunX509 this two algorithm in KeyManagerFactory

So you have to use SunX509 instead of X509.

See the table here

3
votes

Read what the stack trace is telling you:

java.security.NoSuchAlgorithmException: X509 KeyManagerFactory not available

The X509 algorithm is not available from the security provider you are using. However, the following code should work for you:

final KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");

Please have a look at this Code Ranch article which discusses your problem and also shows how to find out which security algorithms are available from your provider.

2
votes

The problem with the use of "SunX509" is that it is specific for an Oracle JRE and doesn't work in an IBM JRE, where the default is "IbmX509". A better solution which is vendor-agnostic is:

KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());

The default algorithm is defined by the security property "ssl.keyManagerFactory.algorithm" in <JRE_HOME>/lib/security/java.security, and is by default "SunX509" in Oracle and "IbmX509" in IBM JREs (at least for Java 8).