Dig into Https client connection in Android
Dig into Https client connection in Android
Table of Contents
- reference resources
- Java Keytool
- Certificate formats
- Use Https in Android Client
- Java SSLContext
- Two ways SSL verification
- TLSDemo
1 reference resources
http://developer.android.com/training/articles/security-ssl.html
http://ogrelab.ikratko.com/using-android-volley-with-self-signed-certificate/ http://stackoverflow.com/questions/2138940/import-pem-into-java-key-store http://stackoverflow.com/questions/3685548/java-keytool-easy-way-to-add-server-cert-from-url-port
http://ogrelab.ikratko.com/using-android-volley-with-self-signed-certificate/ http://stackoverflow.com/questions/2138940/import-pem-into-java-key-store http://stackoverflow.com/questions/3685548/java-keytool-easy-way-to-add-server-cert-from-url-port
2 Java Keytool
Java keystore is like a database which store certificates
and private keys and protect them by a password maybe. There
are at least three formats of that, JKS, PKCS12, JCEKS, and
many more.
But in this tutorial, I only consider two formats of that JKS which is the Java's default format and BKS which is the Android's default format.
How to import a certificate to the BKS style KeyStore? First step was to prepare your certificate at least, the PEM format and DER format is ok. Then to download bcprov-jdk16-146.jar. after that use following command to import an X590 certificate into the keystore.
Import an PEM X509 certificate into JKS keystore:
The default export format of keytool is der format.
But in this tutorial, I only consider two formats of that JKS which is the Java's default format and BKS which is the Android's default format.
How to import a certificate to the BKS style KeyStore? First step was to prepare your certificate at least, the PEM format and DER format is ok. Then to download bcprov-jdk16-146.jar. after that use following command to import an X590 certificate into the keystore.
keytool -importcert -v -trustcacerts -file "my_server_cert.der" -alias key_alias -keystore "my.bks" -provider org.bouncycastle.jce.provider.BouncyCastleProvider -providerpath "bcprov-jdk16-146.jar" -storetype BKS
Import an PEM X509 certificate into JKS keystore:
keytool -importcert -v -trustcacerts -file "cas.pem" -alias cas_alias -keystore "cas.jks" -storetype JKS
The default export format of keytool is der format.
keytool -exportcert -alias cas_alias -keystore "cas.jks" > cas.der
3 Certificate formats
The certificate which I mentioned here are all reference to
X509 format, which is not just the most wildly used, but also
the standard in the PKI industry. The evidence is that there
is Certificate interface in the JDK, but with just only one
child implementation, X509Certificate class.
Now, go back to the point, there are two X509 Certificate formats here, PEM and CER, they are equivalent same things. PEM is base64 encoded format, CER is the binary format.
Using the following cmds to download and convert between each other.
Now, go back to the point, there are two X509 Certificate formats here, PEM and CER, they are equivalent same things. PEM is base64 encoded format, CER is the binary format.
Using the following cmds to download and convert between each other.
#download pem certificate by guntls gnutls-cli --print-cert www.youwebsite.com | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' #download pem certificate by openssl openssl s_client -connect ${HOST}:${PORT} </dev/null | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' # convert DER binary format certificate to PEM base64 encoded format openssl x509 -inform der -in cas.der -outform pem -out cas.pem # convert PEM base64 encoded format certificate to DER binary format openssl x509 -inform pem -in cas.pem -outform der -out cas.der
4 Use Https in Android Client
Before going that, you need to figure out how many http clients in Android.
Basically, there are only two http clients available in Android, HttpUrlConnection
and AndroidHttpClient, which are provided by the system. While HttpUrlConnection
is the barely the only one left now, because AndroidHttpClient and its sibling,
DefaultHttpClient and its parent HttpClient are all deprecated in Android 2.3. So
choose HttpUrlConnection if you wanna wrote any http client code.
And the most of the 3rd party Http Clients are developed above them, Volley, and what ever, except Square's OkHttp, which implements its own http stack.
And the most of the 3rd party Http Clients are developed above them, Volley, and what ever, except Square's OkHttp, which implements its own http stack.
5 Java SSLContext
I think to use SSL programming in java is to understand SSLContext and its
related classes KeyManager, TrustManager, KeyManagerFactory, TrustManagerFactory,
and SSLSocketFactory.
Here is just a piece of code:
While that's not enough, that's why I wrote following demo TLSDemo.
Here is just a piece of code:
KeyStore keyStore = null; try { keyStore = KeyStore.getInstance("BKS"); keyStore.load(in, passwd.toCharArray()); TrustManagerFactory tmf = TrustManagerFactory.getInstance("X509"); tmf.init(keyStore); TrustManager[] tms = tmf.getTrustManagers(); SSLContext sslContext = SSLContext.getInstance("TLS"); sslContext.init(null, tms, null); SSLSocketFactory ssf = sslContext.getSocketFactory(); } catch (KeyStoreException e) { e.printStackTrace(); } catch (CertificateException e) { e.printStackTrace(); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); }
While that's not enough, that's why I wrote following demo TLSDemo.
5 Two-ways SSL verification
Two-ways certificate verification is also named the client side verification, it is part of SSL/TLS
standards.
The normal SSL request process is the client connected to the server and ask for its certificate, the one-way verification. The two-ways verification is the server send the request to client, ask for client's certificate after the normal one-way certificate request.
In this case, the client side must be configured just like the server side, the certificates links and also its private key. In the Android, the client side configuration is really simple, just init the SSLContext with the right KeyManger, check the TLSDemo.
6 TLSDemo
I wrote this demo TLSDemo to illustrate how to use SSL client in Android.
It illustrates following puzzles:
Except the unfinished HttpClient part, TLSDemo is still a good reference of how to use https in UrlConnection, and how SSLContext works?
- How to import certificates in PEM format.
- How to import certificates in BKS type Keystore.
- How to connect https sites with HttpUrlConnection.
Except the unfinished HttpClient part, TLSDemo is still a good reference of how to use https in UrlConnection, and how SSLContext works?
Comments
Post a Comment