{"id":33,"date":"2012-01-14T04:27:47","date_gmt":"2012-01-14T03:27:47","guid":{"rendered":"http:\/\/www.datenzone.de\/blog\/?p=33"},"modified":"2012-01-16T19:26:34","modified_gmt":"2012-01-16T18:26:34","slug":"using-ssltls-client-certificate-authentification-in-android-applications","status":"publish","type":"post","link":"https:\/\/www.datenzone.de\/blog\/2012\/01\/using-ssltls-client-certificate-authentification-in-android-applications\/","title":{"rendered":"Using SSL\/TLS Client Certificate Authentification in Android Applications"},"content":{"rendered":"<p>Assume that you want to write an Android application, that needs to communicate with your server or your wireless router at home, for personal use. You might be interested in securing this communication against eavesdropping, so that nobody else sees, what you application sends and receives. You also might be interested in authenticating you communication, so that you can be sure that only your application and your server or router communicate, and nobody else is able to modify the content transmitted, without being noticed. The SSL\/TLS protocol is a perfect solution for this problem, so that you don&#8217;t need to invent a solution yourself.<\/p>\n<h1>Certificates<\/h1>\n<p>To ensure authenticity of both communication partners, X.509 certificates can be used. Most secure websites in the internet like paypal, ebay, or amazon only use X.509 certificates for the server, and the client is authenticated using a username and a password. For this example, X.509 certificates will be used for both communication partners.<\/p>\n<p>To generate two self-signed X.509 certificates, the following script can be used. It will generate two new RSA 2048 bit keys, generate two self signed certificates, and bundle the client certificate with the corresponding private key, and the servers public certificate in a PKCS#12 container file.<\/p>\n<pre lang=\"bash\">#!\/bin\/bash\r\nOPENSSL_OPTS=\"-new -newkey rsa:2048 -nodes -days 5475 -x509\"\r\nCN_SERVER=\"\/CN=server\"\r\nCN_CLIENT=\"\/CN=client\"\r\nPASS=\"123456\"\r\necho \"Generating keys\"\r\nopenssl req -keyout key-server.pem -subj \"$CN_SERVER\" \\\r\n -out cert-server.pem $OPENSSL_OPTS\r\nopenssl req -keyout key-client.pem -subj \"$CN_CLIENT\"\\\r\n -out cert-client.pem $OPENSSL_OPTS\r\necho \"Encrypting key for the client now\"\r\nopenssl pkcs12 -export -passout \"pass:$PASS\" \\\r\n -in cert-client.pem -inkey key-client.pem -out client.p12 \\\r\n -certfile cert-server.pem -name \"Client\" -caname \"Server\"<\/pre>\n<h1>Stunnel<\/h1>\n<p>We will use stunnel for the server. Stunnel is a lightweight general SSL\/TLS wrapper and proxy. First, we copy cert-client.pem cert-server.pem and key-server.pem to the server to \/etc\/ssl\/stunnel or another directory. Next is the stunnel configuration file:<\/p>\n<pre lang=\"text\">cert = \/etc\/ssl\/stunnel\/cert-server.pem\r\nkey = \/etc\/ssl\/stunnel\/key-server.pem\r\nCAfile = \/etc\/ssl\/stunnel\/cert-client.pem\r\nsslVersion = SSLv3\r\nchroot = \/var\/lib\/stunnel4\/\r\nsetuid = stunnel4\r\nsetgid = stunnel4\r\npid = \/stunnel4.pid\r\nsocket = l:TCP_NODELAY=1\r\nsocket = r:TCP_NODELAY=1\r\n[service]\r\naccept  = 1279\r\nconnect = target:1280\r\nverify = 2<\/pre>\n<p>This will set up a stunnel server, listening on port 1279, and forwarding the unencrypted communication to target port 1280. It will only allow connections from a client, presenting a valid certificate.<\/p>\n<h1>Android<\/h1>\n<p>Next, we can write the code for our Android application:<\/p>\n<pre lang=\"java\">\r\n\/\/ Adopt this in your application\r\nString PASSWORD_FOR_PKCS12 = \"123456\";\r\nInputStream pkcs12in = ......\r\n\/\/ You only need to execute this code once\r\nSSLContext context = SSLContext.getInstance(\"TLS\");\r\n\/\/ Local client certificate and key and server certificate\r\nKeyStore keyStore = KeyStore.getInstance(\"PKCS12\");\r\nkeyStore.load(pkcs12in, PASSWORD_FOR_PKCS12.toCharArray());\r\n\/\/ Build a TrustManager, that trusts only the server certificate\r\nTrustManagerFactory tmf = TrustManagerFactory.getInstance(\"X509\");\r\nKeyStore keyStoreCA = KeyStore.getInstance(\"BKS\");\r\nkeyStoreCA.load(null, null);\r\nCertificate c = keyStore.getCertificate(\"Server\");\r\nkeyStoreCA.setCertificateEntry(\"Server\", c);\r\ntmf.init(keyStoreCA);\r\n\/\/ Build a KeyManager for Client auth\r\nKeyManagerFactory kmf = KeyManagerFactory.getInstance(\r\n        KeyManagerFactory.getDefaultAlgorithm());\r\nkmf.init(keyStore, null);\r\ncontext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);\r\n\/\/ Everytime you need your https connection, run this code\r\nURL url = new URL(\"https:\/\/my-router:1279\/\");\r\nHttpsURLConnection urlConnection = (HttpsURLConnection) url.openConnection();\r\nurlConnection.setSSLSocketFactory(context.getSocketFactory());\r\nurlConnection.setHostnameVerifier(new AllowAllHostnameVerifier());\r\nInputStream in = urlConnection.getInputStream();\r\n<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>Assume that you want to write an Android application, that needs to communicate with your server or your wireless router at home, for personal use. You might be interested in securing this communication against eavesdropping, so that nobody else sees, &hellip;<\/p>\n<p class=\"read-more\"><a href=\"https:\/\/www.datenzone.de\/blog\/2012\/01\/using-ssltls-client-certificate-authentification-in-android-applications\/\">Read more &raquo;<\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[3,4],"tags":[],"class_list":["post-33","post","type-post","status-publish","format-standard","hentry","category-android","category-crypto"],"_links":{"self":[{"href":"https:\/\/www.datenzone.de\/blog\/wp-json\/wp\/v2\/posts\/33","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.datenzone.de\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.datenzone.de\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.datenzone.de\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.datenzone.de\/blog\/wp-json\/wp\/v2\/comments?post=33"}],"version-history":[{"count":6,"href":"https:\/\/www.datenzone.de\/blog\/wp-json\/wp\/v2\/posts\/33\/revisions"}],"predecessor-version":[{"id":38,"href":"https:\/\/www.datenzone.de\/blog\/wp-json\/wp\/v2\/posts\/33\/revisions\/38"}],"wp:attachment":[{"href":"https:\/\/www.datenzone.de\/blog\/wp-json\/wp\/v2\/media?parent=33"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.datenzone.de\/blog\/wp-json\/wp\/v2\/categories?post=33"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.datenzone.de\/blog\/wp-json\/wp\/v2\/tags?post=33"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}