Socket.io-client-java: Android SSL (self signed certificate) implementation

Created on 25 Mar 2016  路  6Comments  路  Source: socketio/socket.io-client-java

While implementing SSL socket connection based on native Android I used the below code, which worked fine.
Now, if I've to implement a similar thing using socket.io, what's the procedure for that?

`KeyStore ks = KeyStore.getInstance("BKS");
                        InputStream keyin = v.getResources().openRawResource(R.raw.keystore);
                        ks.load(keyin, keystorepass);
                        SSLSocketFactory socketFactory = new SSLSocketFactory(ks);
                        socketFactory.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
                        socket = (SSLSocket)
                                socketFactory.createSocket(new Socket(ip_address, port), ip_address, port, false);
                        socket.startHandshake();

                        printServerCertificate(socket);
                        printSocketInfo(socket);

                        out = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
                        in = new BufferedReader(new InputStreamReader(socket.getInputStream()));

Most helpful comment

    public static void configureSocketForSSL() {
        try {

            // Load cert
            byte[] der = Configuration.SERVER_CERT.getBytes();
            ByteArrayInputStream derInputStream = new ByteArrayInputStream(der);
            CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
            X509Certificate cert = (X509Certificate) certificateFactory.generateCertificate(derInputStream);
            String alias = cert.getSubjectX500Principal().getName();

            // Create keystore and add to ssl context
            KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
            trustStore.load(null);
            trustStore.setCertificateEntry(alias, cert);

            KeyManagerFactory kmf = KeyManagerFactory.getInstance("X509");
            kmf.init(trustStore, null);
            KeyManager[] keyManagers = kmf.getKeyManagers();

            TrustManagerFactory tmf = TrustManagerFactory.getInstance("X509");
            tmf.init(trustStore);
            TrustManager[] trustManagers = tmf.getTrustManagers();

            SSLContext sslContext = SSLContext.getInstance("TLS");
            sslContext.init(keyManagers, trustManagers, null);

            // Add SSL-context and hostname verification
            IO.setDefaultSSLContext(sslContext);
            IO.setDefaultHostnameVerifier(new RelaxedHostNameVerifier());


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


    /**
     * Inner class to verify hostname --> Allow all hostname's
     */
    public static class RelaxedHostNameVerifier implements HostnameVerifier {
        public boolean verify(String hostname, SSLSession session) {
            return true;
        }
    }

Works like a charm :)

The other examples are sooo unsafe, because there accept all certs with all hostnames ... so why there using HTTPs at all ?!

I used this Post from Rich Freedman

All 6 comments

    public static void configureSocketForSSL() {
        try {

            // Load cert
            byte[] der = Configuration.SERVER_CERT.getBytes();
            ByteArrayInputStream derInputStream = new ByteArrayInputStream(der);
            CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
            X509Certificate cert = (X509Certificate) certificateFactory.generateCertificate(derInputStream);
            String alias = cert.getSubjectX500Principal().getName();

            // Create keystore and add to ssl context
            KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
            trustStore.load(null);
            trustStore.setCertificateEntry(alias, cert);

            KeyManagerFactory kmf = KeyManagerFactory.getInstance("X509");
            kmf.init(trustStore, null);
            KeyManager[] keyManagers = kmf.getKeyManagers();

            TrustManagerFactory tmf = TrustManagerFactory.getInstance("X509");
            tmf.init(trustStore);
            TrustManager[] trustManagers = tmf.getTrustManagers();

            SSLContext sslContext = SSLContext.getInstance("TLS");
            sslContext.init(keyManagers, trustManagers, null);

            // Add SSL-context and hostname verification
            IO.setDefaultSSLContext(sslContext);
            IO.setDefaultHostnameVerifier(new RelaxedHostNameVerifier());


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


    /**
     * Inner class to verify hostname --> Allow all hostname's
     */
    public static class RelaxedHostNameVerifier implements HostnameVerifier {
        public boolean verify(String hostname, SSLSession session) {
            return true;
        }
    }

Works like a charm :)

The other examples are sooo unsafe, because there accept all certs with all hostnames ... so why there using HTTPs at all ?!

I used this Post from Rich Freedman

What is your "Configuration.SERVER_CERT"? I'm trying to get SSL working with a self-signed certificate, but when I tried to use your code block, that's the only part that seemed to barf.

This is just a class for some configurations and static properties, like the public server cert

public class Configuration {
    /**
     * Server cert
     */
    public static final String SERVER_CERT = "-----BEGIN CERTIFICATE-----\n" +
            ....
            "-----END CERTIFICATE-----\n";

Alright, so we're using your configure block to return an ssl context, setting the context on the IO options, and then passing the options in when creating our socket. Still a no-go. Is there a way to turn on logging for the SocketIO portion? We haven't been able to find that either. Here's a snippet of the code we're doing:

` protected SocketFactory(){
try {
IO.Options socketOptions = new IO.Options();
SSLContext sslContext = configureSocketForSSL();

        socketOptions.sslContext = sslContext;
        socketOptions.hostnameVerifier = new RelaxedHostNameVerifier();
        //socketOptions.secure = true;
        signalingSocket = IO.socket(signalingURI, socketOptions);

        signalingSocket.on("connecting", onConnecting);
        signalingSocket.on("connected", onConnected);
        signalingSocket.connect();
    }
    catch(Exception exception){
        exception.printStackTrace();
    }
}

private static SSLContext configureSocketForSSL() {
    try {
        // Load cert
        byte[] der = SERVER_CERT.getBytes();
        ByteArrayInputStream derInputStream = new ByteArrayInputStream(der);
        CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
        X509Certificate cert = (X509Certificate) certificateFactory.generateCertificate(derInputStream);
        String alias = cert.getSubjectX500Principal().getName();

        // Create keystore and add to ssl context
        KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
        trustStore.load(null);
        trustStore.setCertificateEntry(alias, cert);

        KeyManagerFactory kmf = KeyManagerFactory.getInstance("X509");
        kmf.init(trustStore, null);
        KeyManager[] keyManagers = kmf.getKeyManagers();

        TrustManagerFactory tmf = TrustManagerFactory.getInstance("X509");
        tmf.init(trustStore);
        TrustManager[] trustManagers = tmf.getTrustManagers();

        SSLContext sslContext = SSLContext.getInstance("TLS");
        sslContext.init(keyManagers, trustManagers, null);

        return sslContext;

    } catch (Exception e) {
        e.printStackTrace();
    }
    return null;
} `

byte[] der = Configuration.SERVER_CERT.getBytes();姹傝В

Fur future reference, IO.setDefaultSSLContext() and IO.setDefaultHostnameVerifier() are not longer available.

The documentation shows how to do this by configuring an OkHttpClient and using the methods IO.setDefaultWebSocketFactory() and IO.setDefaultCallFactory()

Was this page helpful?
0 / 5 - 0 ratings

Related issues

pareshdevatval picture pareshdevatval  路  4Comments

arora-arpit picture arora-arpit  路  3Comments

jaumard picture jaumard  路  4Comments

jingfreeks picture jingfreeks  路  3Comments

cmarrero01 picture cmarrero01  路  15Comments