Tuesday, March 2, 2010

PAW Server for Android and SSL

After receiving user feedback from Stephen I decided to have a look how to implement SSL connections for PAW.

As Stephen pointed out, and of course he is correct, security is not very high in PAW as it is possible to modify data on the device.
First thing I did was to check how SSL works on standard Java.
This was fairly easy and worked on first try:

int port = 9999;
System.setProperty("javax.net.ssl.keyStore", "android-keystore");
System.setProperty("javax.net.ssl.keyStorePassword", "android");
ServerSocketFactory ssocketFactory = SSLServerSocketFactory.getDefault();
ServerSocket ssocket = ssocketFactory.createServerSocket(port);
Socket socket = ssocket.accept();

Unfortunately that didn't work at all on Android. I only received an normal ServerSocket without any SSL support.
After some googeling the code looked like this:

import javax.net.ssl.SSLServerSocketFactory;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.KeyManagerFactory;
import java.security.KeyStore;

try {
    int port = 9999;
    char[] passphrase = "android".toCharArray();

 ctx = SSLContext.getInstance("TLS");

 kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
 //BKS
 ks = KeyStore.getInstance (KeyStore.getDefaultType());

 ks.load(new FileInputStream("/sdcard/pawKeystore"),passphrase);
 kmf.init(ks, passphrase);
 ctx.init(kmf.getKeyManagers(), null, null);

 ssf = ctx.getServerSocketFactory();
 ssocket = ssf.createServerSocket(port);
 ssocket.accept();

} catch (e) {
    print(e);
}

This code is in principle working. Actually the code can be executed inside the PAW BeanShell Console (if a keystore exists).

What I didn't know was that the keystore format on Android is not the same as in standard Java. The format uses by Android is BKS which is not supported by the Java keytool out of the box.

To get BKS working the JCE provider from BouncyCastle has to be downloaded and the JAR file has to be extracted to $JAVA_HOME/jre/lib/ext/. After that the following line has to be added to the file $JAVA_HOME/jre/lib/security/java.security:

security.provider.9=org.bouncycastle.jce.provider.BouncyCastleProvider

The number behind security.provider. depends on your Java installation. After that a keystore file can be created with the following command line:

keytool -genkey -keyalg RSA -keysize 1024 -alias alias -keystore pawKeystore -validity 3650 -storetype BKS

On my Galaxy I noticed that when running the code not all connections were accepted, which was strange. In addition there would be minor changes necessary to the underlying Brazil framework, because SSLSockets throw additional Exceptions which do not occur when standard  Sockets are used.

But after setting it all up it didn't work because of connection problems and when it worked from time to time it was horribly slow.
The connections problems might be a problem within Android, because for the application this all should be transparent.

I would have really liked to implement SSL within PAW but at the moment I just don't get it working.

3 comments:

  1. Hello,
    I am using PAW server on my Android device. I tried to access my android device from remote PC, but it not accessible. If I try to access on local browser in the device, it works. I am using 3G internet connection. Please tell me if i am missing something here.

    thanks,Krishna
    krishna.shetty.h@gmail.com

    ReplyDelete
  2. Hi Krishna,

    if PAW works over 3G depends on your carrier.
    A lot of carriers block ports or use NAT. If this is the case 3G will not work.
    WiFi should work in any case.

    ReplyDelete

Note: Only a member of this blog may post a comment.