3

I'm new on Android platform, coming from .NET world. I need to write a TCP/SSL client class in my app, which send/recieve text messages with some Java server. I also need to use server public certificate (.cer file) in that communication. In C# I have SSLStream class that do all the job, and a lot of examples for it. However for Android (Lolipop) I cannot find any good examples on this subject, especially without http protocol on top. Any hint would be appreciated.

1
  • Welcome to SO:SE. See How to Ask to understand how the site works and improve your post. Two comments... It seems you are asking without previous research on your side, and there are many tutorial on this basic topic online. Commented Apr 26, 2015 at 8:43

2 Answers 2

6

Below is basially steps to create ssl connection in android :

Step 1 : Get public key of ur server (.cert file), which you already have.

Step 2: Create keystore via bouncycastle jar

Below is commands :

keytool -importcert -v -trustcacerts -file "path_to_cert/interm_ca.cer" -alias IntermediateCA -keystore "res/raw/myKeystore.bks" -provider org.bouncycastle.jce.provider.BouncyCastleProvider -providerpath "path_to_bouncycastle/bcprov-jdk16-145.jar" -storetype BKS -storepass mysecret

Verify if the certificates were imported correctly into the keystore:

keytool -list -keystore "res/raw/myKeystore.bks" -provider org.bouncycastle.jce.provider.BouncyCastleProvider -providerpath "path_to_bouncycastle/bcprov-jdk16-145.jar" -storetype BKS -storepass mysecret

Should output the whole chain:

RootCA, 22.10.2010, trustedCertEntry, Thumbprint (MD5): 24:77:D9:A8:91:D1:3B:FA:88:2D:C2:FF:F8:CD:33:93IntermediateCA, 22.10.2010, trustedCertEntry, Thumbprint (MD5): 98:0F:C3:F8:39:F7:D8:05:07:02:0D:E3:14:5B:29:43

Now you can copy the keystore as a raw resource in your android app under res/raw/

Step 3:

Create HttpsClient like below and query you service with this client only :

public class HttpsClient extends DefaultHttpClient {

    final Context context;

    public HttpsClient(Context context) {
        this.context = context;
    }

    @Override
    protected ClientConnectionManager createClientConnectionManager() {
        SchemeRegistry registry = new SchemeRegistry();
        registry.register(new Scheme("http", PlainSocketFactory
                .getSocketFactory(), 80));
        // Register for port 443 our SSLSocketFactory with our keystore
        // to the ConnectionManager
        registry.register(new Scheme("https", newSslSocketFactory(), 443));
        return new SingleClientConnManager(getParams(), registry);
    }

    private SSLSocketFactory newSslSocketFactory() {
        try {
            // Get an instance of the Bouncy Castle KeyStore format
            KeyStore trusted = KeyStore.getInstance("BKS");
            // Get the raw resource, which contains the keystore with
            // your trusted certificates (root and any intermediate certs)
            InputStream in = context.getResources().openRawResource(
                    R.raw.mykeystore);
            try {
                // Initialize the keystore with the provided trusted
                // certificates
                // Also provide the password of the keystore
                trusted.load(in, "mysecret".toCharArray());
            } finally {
                in.close();
            }
            // Pass the keystore to the SSLSocketFactory. The factory is
            // responsible
            // for the verification of the server certificate.
            SSLSocketFactory sf = new SSLSocketFactory(trusted);
            // Hostname verification from certificate
            sf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
            return sf;
        } catch (Exception e) {
            throw new AssertionError(e);
        }
    }
}

The Above Case holds true for connection over http , if you need to have connection without http , the keystore procedure remains the same and you need to use sockets to open and close the connection :

String keyStorePath = "absolute path to your JKS keystore file";
String keyStorePass = "keystore password";

System.setProperty("javax.net.ssl.keyStore", keyStorePath);
System.setProperty("javax.net.ssl.keyStorePassword", keyStorePass);

SSLServerSocketFactory sslserversocketfactory = (SSLServerSocketFactory) SSLServerSocketFactory.getDefault();
SSLServerSocket serverSocket = (SSLServerSocket) sslserversocketfactory.createServerSocket(port_number);

while (true) {
    new ClientThread((SSLSocket) serverSocket.accept()).start();
}
Sign up to request clarification or add additional context in comments.

4 Comments

thanks on the anwser. However, I don't need HTTP client, just TCP/SSL client.
HttpsClient client above is created for ssl connection only
I now. But, I'm not using http, beacuse my server is some kind of a transaction server (not web), and it uses only tcp/ip layer and ssl on the top to send/receive plaing text messages.
possibly this is smiliar to what i am saying : examples.javacodegeeks.com/android/core/socket-core/…
0

the KOTIOS answer Works!

For SSL sockets (not http)

use this code:

        Socket socket = null;
        SSLContext  context = null;
        char[] passphrase = "mysecret".toCharArray();
        try{
            KeyStore keystore =  KeyStore.getInstance("BKS");
            keystore.load(this.getApplication().getResources().openRawResource(R.raw.mykeystore), passphrase);
            TrustManagerFactory   tmf = TrustManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
            tmf.init(keystore);
            context = SSLContext.getInstance("TLS");
            TrustManager[] trustManagers = tmf.getTrustManagers();
            context.init(null, trustManagers, null);
        }catch (Exception e){
            e.printStackTrace();
        }

        SSLSocketFactory sf = context.getSocketFactory();
        socket = (SSLSocket) sf.createSocket(InetAddress.getByName(IP), DEFAULT_PORT);

and use this socket like a normal socket.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.