Software I used for configuring the SSL connection and developing android app are listed below. I configured the system in Windows 7. So I used windows distributions for almost all of these software.
- Apache server (I used Apache 2.2)
- OpenSSL Windows executable
- BouncyCastle Provider
- Portecle
- Java Standard Oracle distribution
- Eclipse
- Eclipse plug-in for Android : Android Development Tools (ADT)
- Android SDK
Step 1:
openssl genrsa -out ca.key 1024
openssl req -new -key ca.key -out ca.csr -config path/to/openssl.cfg
openssl x509 -req -days 365 -in ca.csr -signkey ca.key -out ca.crt
(2)Setup the Web Server Certificate
For Apache server, create private key and server certificate using the same commands mentioned above:
openssl genrsa -out server.key 1024
openssl req -new -key server.key -out server.csr -config openssl.cfg
openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt
<VirtualHost _default_:443>ServerAdmin some@email.comDocumentRoot "Your Root folder location"ServerName www.domain.com:443ServerAlias domain.com:443ErrorLog "logs/anyFile-error.log"CustomLog "logs/anyFile-access.log" commonSSLEngine onSSLCertificateFile "[apache installation folder]/conf/server.crt"SSLCertificateKeyFile "[apache installation folder]/conf/server.key"SSLCACertificateFile "[apache installation folder]/conf/ssl.crt/ca.crt"</VirtualHost>
Step 2:
openssl genrsa -out client.key 1024
openssl req -new -key client.key -out client.csr -config openssl.cfg
openssl x509 -req -days 365 -CA ca.crt -CAkey ca.key -CAcreateserial -in client.csr -out client.crt
openssl pkcs12 -export -clcerts -in client.crt -inkey client.key -out client.p12
Step 3:
Converting server and client certificate in Android specific format
Now you have the server certificate “server.crt” and client certificate "client.p12". If you want to use the server and client certificate in android application, you need to convert the certificate in BKS format because android accept only that format..P12 file. Save the
key store by providing a password of your choice. keytool -import -v -trustcacerts -alias 0 -file "[apache installation folder]/conf/server.crt" -keystore "/path/of/bksfile/client.bks" -storetype BKS -provider org.bouncycastle.jce.provider.BouncyCastleProvider -providerpath "path/of/bcprov-jdk15on-146.jar" -storepass password
Here you have specified the input server.crt, output client. bks, the provider name, in this case BouncyCastleProvider and the path of the provider file.
The MainActivity code can be found here.
And the SSL connection code can be found here
Step 4:
SSLVerifyClient require
SSLVerifyDepth 10
SSLSocketFactory socketFactory = new SSLSocketFactory(trustStore);
SSLSocketFactory socketFactory = new SSLSocketFactory(SSLSocketFactory.TLS, keyStore, "keystore password", trustStore, null, null);
Step 5:
Using HTTP Put for uploading files from Android to the server
So far you have the 2-way SSL connection between Apache server and the android client. Now time to upload files to the server from android device. For that you again need to configure Apache server and add some code in your android app.
LoadModule alias_module modules/mod_alias.soLoadModule auth_digest_module modules/mod_auth_digest.soLoadModule authn_file_module modules/mod_authn_file.soLoadModule dav_module modules/mod_dav.soLoadModule dav_fs_module modules/mod_dav_fs.soLoadModule dav_lock_module modules/mod_dav_lock.soLoadModule setenvif_module modules/mod_setenvif.so
Include conf/extra/httpd-dav.conf
htdigest -c "[apache installation folder]/user.passwd" DAV-upload admin
DavLockDB "[apache installation folder]/var/DavLock"Alias /htdocs "[apache installation folder]/[the folder where user will upload their files]"<Directory "[apache installation folder]/[the folder where user will upload their files">Dav OnOrder Allow,DenyAllow from allAuthType DigestAuthName DAV-upload# You can use the htdigest program to create the password database:# htdigest -c "[apache installation folder]/user.passwd" DAV-upload adminAuthUserFile "path/of/user.passwd"AuthDigestProvider file# Allow universal read-access, but writes are restricted# to the admin user.<LimitExcept GET OPTIONS>require user admin</LimitExcept></Directory>
final String username = "admin";
final String password = "password for WEBDAV";
UsernamePasswordCredentials c = new UsernamePasswordCredentials(username,password);
BasicCredentialsProvider cP = new BasicCredentialsProvider();
cP.setCredentials(AuthScope.ANY, c);
sClient.setCredentialsProvider(cP);
(6) Add the following code for uploading files.
String filepath="https://10.0.2.2/" + filename;
HttpPut httpPut = new HttpPut(filepath);
httpPut.setEntity(new StringEntity(fileContent));
HttpResponse response2 = sClient.execute(httpPut);
HttpEntity httpEntity2 = response2.getEntity();
Log.i("Mainactivity", "result " + response2.getStatusLine().getStatusCode());
Log.i("Mainactivity", "response " + response2.getStatusLine()); responseCode=response2.getStatusLine().getStatusCode();
if (response2.getStatusLine().getStatusCode() == 200)
{
InputStream is2 = response2.getEntity().getContent();
int ch;
StringBuffer sb = new StringBuffer();
while ((ch = is2.read()) != -1) {
sb.append((char) ch);
}
Log.i("Mainactivity", "result inside " + sb.toString());
}
}
Some points that needs attention.
Useful links:
- http://www.impetus.us/~rjmooney/projects/misc/clientcertauth.html
- http://stackoverflow.com/questions/8311295/how-to-use-p12-certificates-in-android-client-certificates
- http://stackoverflow.com/questions/4064810/using-client-server-certificates-for-two-way-authentication-ssl-socket-on-androi
- http://portecle.sourceforge.net/
- http://stackoverflow.com/questions/4206039/android-fileupload-with-https-and-credentials
- http://www.mkyong.com/apache/how-to-enable-webdav-in-apache-server-2-2-x-windows/
- http://blog.antoine.li/2010/10/22/android-trusting-ssl-certificates/