Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How Can I Access an SSL Connection Through Android?

I started following a tutorial that wasn't cased around Android and got this:

    System.setProperty("javax.net.ssl.trustStore", "truststore");
    System.setProperty("javax.net.ssl.trustStorePassword", "password");

    SSLSocketFactory ssf = (SSLSocketFactory) SSLSocketFactory.getDefault();
    try {
        Socket s = ssf.createSocket("192.168.2.11", 6543);
        PrintWriter out = new PrintWriter(s.getOutputStream());
        while (true){
            out.println("SSL TEST");
            Log.d("DATA", "DATA SENT");
        }



    } catch (UnknownHostException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

I guess this boils down to a few questions:

  1. I do not have my own trust store created, but searching through tutorials and things online, I am not sure how to create one. Is there a way I can create or modify a trust store to have the certificates I need in it? (I am using a self-signed certificate if that makes any difference)

  2. How do I make things with the SSL handshake run smoothly? Right now, the error I am getting is:

    javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.
    

    Honestly, I don't really understand what that means.

  3. What settings or files do I need to modify on my Android device to make sure this connection can happen?

like image 672
Matt Avatar asked Jun 22 '11 14:06

Matt


2 Answers

1) It depends. Do you have a self signed cert on the server side and you are trying to validate your identity to the android device? Or are you on the android side trying to validate your idendity to the server? If it is the former , then please see this link: http://www.codeproject.com/KB/android/SSLVerification_Android.aspx?display=Mobile

You want to pay particular attention to where it makes the KeyStore file.

2) The reason you're getting that error is because it doesn't trust the server you are connecting either because you did not create the truststore correctly or you are connecting to a server whose certificate has not been added to the truststore. What exactly are you trying to connect to?

3) Make sure you have the <uses-permission android:name="android.permission.INTERNET" /> in the manifest.xml.

Edit My apologies, please see the changes I made to the first paragraph.

Here is the part to initialize your keystore and truststore

SSLcontext sslContext = SSLContext.getDefault();

KeyStore trustSt = KeyStore.getInstance("BKS");
TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
InputStream trustStoreStream = this.getResources().openRawResource(R.raw.truststore);
trustSt.load(trustStoreStream, "<yourpassword>".toCharArray());
trustManagerFactory.init(trustStre);

KeyStore keyStore = KeyStore.getInstance("BKS");
KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
InputStream keyStoreStream = this.getResources().openRawResource(R.raw.keystore);
keyStore.load(keyStoreStream, "<yourpassword>".toCharArray());
keyManagerFactory.init(keyStore, "<yourpassword>".toCharArray());

sslContext.init(keyManagerFactory.getKeyManagers(), trustManagerFactory.getTrustManagers(), null);
like image 178
Otra Avatar answered Sep 24 '22 21:09

Otra


You don't need your own truststore unless the peer is using self-signed certifictes. The JRE ships with a truststore that is used by default, which trusts certificates issued by all the major CAs.

like image 25
user207421 Avatar answered Sep 24 '22 21:09

user207421