0

I'm developing an Android Application and need to provide a SSL-secured TCP-Server using my own SSL-certificate. I have the following files:

  • server.crt
  • server.key (private)
  • my-ca.crt

1) Certificate creation:
As explained in this SO I've used the command-line tool 'keytool' to create a BKS-keystore from mycert.pem. An put it the /res/raw folder of my application I'm not sure what to do with the private key though, I don't need it for certificate creation do I?

2) Server-Code:

String keyStoreType = KeyStore.getDefaultType();
KeyStore keyStore = KeyStore.getInstance(keyStoreType);
KeyStore.load(context.getResouces().openRawResource(R.raw.mykeystore), "mypass".toCharArray();

String keyalg = KeyManagerFactory.getDefaultAlgorithm();
KeyManagerFactory kmf = KeyManagerFactory.getInstance(keyalg);
kmf.init(keyStore, "mypass".toCharArray());


SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(kmf.getKeyManagers(), null, null);
SSLServerSocket serverSocket = (SSLServerSocket)sslContext.getServerSocketFactory().createServerSocket(3333);

SSLSocket sslSocket = (SSLSocket) sslServerSocket.accept();

//not shown: create BufferedReader from sslSocket.getInputStream(), while-loop for incoming messages

3) Client code:
I wrote a dummy java client containing this code:

SSLSocketFactory sslSocketFactory = (SSLSocketFactory) SSLSocketFactory.getDefault();
SSLSocket sslsocket = (SSLSocket) sslsocketfactory.createSocket("192.168.2.101", 3333);
sslsocket.startHandshake();

And run it by calling:

java -Djavax.net.ssl.trustStore=keystore -Djavax.net.ssl.trustStorePassword=password client passing the same keystore I've created for my server.

When calling startHandshake() the client throws a SSLHandshakeException, saying "PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target".

For both client and server I use same keystore containing only the server.crt file. Might that be the root of the problem? Do I have to use the private key (server.key) and/or the ca-cert to make this work? Any other suggestions?

Any help is greatly appreciated. Thanks in advance.

Androidicus
  • 1,688
  • 4
  • 24
  • 36

1 Answers1

0

I think I've figured it out. It was quite a hassle so if anyone ever has the same kind of problem here's what if done. I've created a new pkcs12 keystore adding server.crt, server.key and the ca.crt by calling:

openssl pkcs12 -export -in cert.pem -inkey key.pem -out server.p12 -name server -CAfile cacert.pem -caname root

Android only accepts BKS files so I needed to convert this. A direct conversion using the tool portecle didn't work as pkcs12 to bks requires bouncy castle 1.5 but android only support bouncy castle 1.46. So I downloaded both version of bouncy castle. First I added version 1.5 and converted the pkcs12 to a JRE file (there are SO answers for that one).

Then I replaced version 1.5 with 1.46 and converted the JRE to BKS again using portecle.

After that you only need to add the keystore to /res/raw in Android and use it as shown in the code above.

Hope this helps someone.

Androidicus
  • 1,688
  • 4
  • 24
  • 36