Security With HTTPS and SSL Android Developers
Security With HTTPS and SSL Android Developers
6/2/2014 9:20 PM
s_client
$ openssl s_client -connect wikipedia.org:443 | openssl x509 -noout -subject -issuer subject= /serialNumber=sOrr2rKpMVP70Z6E9BT5reY008SJEdYv/C=US/O=*.wikipedia.org/OU=GT03314600/ issuer= /C=US/O=GeoTrust, Inc./CN=RapidSSL CA
http://developer.android.com/training/articles/security-ssl.html
1 of 7
6/2/2014 9:20 PM
URL url = new URL("https://wikipedia.org"); URLConnection urlConnection = url.openConnection(); InputStream in = urlConnection.getInputStream(); copyInputStreamToOutputStream(in, System.out);
HttpURLConnection HttpURLConnection
(/reference/java/net/HttpURLConnection.html) (/reference/java/net/HttpURLConnection.html)
getInputStream()
/URLConnection.html#getInputStream())
(/reference/java/net
javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: T at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.startHandshake(Ope at libcore.net.http.HttpConnection.setupSecureSocket(HttpConnection.java:209) at libcore.net.http.HttpsURLConnectionImpl$HttpsEngine.makeSslConnection(Http at libcore.net.http.HttpsURLConnectionImpl$HttpsEngine.connect(HttpsURLConnec at libcore.net.http.HttpEngine.sendSocketRequest(HttpEngine.java:290) at libcore.net.http.HttpEngine.sendRequest(HttpEngine.java:240) at libcore.net.http.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.j at libcore.net.http.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImp at libcore.net.http.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionI
SSLHandshakeException
(/reference/javax/net/ssl/SSLHandshakeException.html)
HttpsURLConnection InputStream
(/reference/javax/net/ssl/HttpsURLConnection.html)
(/reference/java/io/InputStream.html)
KeyStore TrustManager
(/reference
/java/security/KeyStore.html) /net/ssl/TrustManager.html)
(/reference/javax
TrustManager
(/reference/javax/net/ssl/TrustManager.html)
KeyStore
(/reference
http://developer.android.com/training/articles/security-ssl.html
2 of 7
6/2/2014 9:20 PM
/java/security/KeyStore.html)
TrustManager
(/reference/javax/net/ssl/TrustManager.html) (/reference/javax/net/ssl/TrustManager.html)
TrustManager SSLContext
(/reference/javax/net/ssl/SSLContext.html)
SSLSocketFactory SSLSocketFactory
(/reference/javax/net/ssl
HttpsURLConnection
// Load CAs from an InputStream // (could be from a resource or ByteArrayInputStream or ...) CertificateFactory cf = CertificateFactory.getInstance("X.509"); // From https://www.washington.edu/itconnect/security/ca/load-der.crt InputStream caInput = new BufferedInputStream(new FileInputStream("load-der.crt" Certificate ca; try { ca = cf.generateCertificate(caInput); System.out.println("ca=" + ((X509Certificate) ca).getSubjectDN()); } finally { caInput.close(); } // Create a KeyStore containing our trusted CAs String keyStoreType = KeyStore.getDefaultType(); KeyStore keyStore = KeyStore.getInstance(keyStoreType); keyStore.load(null, null); keyStore.setCertificateEntry("ca", ca); // Create a TrustManager that trusts the CAs in our KeyStore String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm(); TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm); tmf.init(keyStore); // Create an SSLContext that uses our TrustManager SSLContext context = SSLContext.getInstance("TLS"); context.init(null, tmf.getTrustManagers(), null); // Tell the URLConnection to use a SocketFactory from our SSLContext URL url = new URL("https://certs.cac.washington.edu/CAtest/"); HttpsURLConnection urlConnection = (HttpsURLConnection)url.openConnection(); urlConnection.setSSLSocketFactory(context.getSocketFactory()); InputStream in = urlConnection.getInputStream(); copyInputStreamToOutputStream(in, System.out);
TrustManager
(/reference/javax/net/ssl/TrustManager.html)
TrustManager
(/reference/javax/net/ssl/TrustManager.html)
TrustManager
(/reference/javax/net/ssl/TrustManager.html)
http://developer.android.com/training/articles/security-ssl.html
3 of 7
6/2/2014 9:20 PM
SSLHandshakeException
(/reference/javax/net/ssl/SSLHandshakeException.html)
TrustManager
(/reference/javax/net/ssl/TrustManager.html)
SSLHandshakeException
(/reference/javax/net/ssl/SSLHandshakeException.html)
openssl s_client $ openssl s_client -connect mail.google.com:443 --Certificate chain 0 s:/C=US/ST=California/L=Mountain View/O=Google Inc/CN=mail.google.com i:/C=ZA/O=Thawte Consulting (Pty) Ltd./CN=Thawte SGC CA 1 s:/C=ZA/O=Thawte Consulting (Pty) Ltd./CN=Thawte SGC CA i:/C=US/O=VeriSign, Inc./OU=Class 3 Public Primary Certification Authority ---
$ openssl s_client -connect egov.uscis.gov:443 --Certificate chain 0 s:/C=US/ST=District Of Columbia/L=Washington/O=U.S. Department of Homeland Securit i:/C=US/O=VeriSign, Inc./OU=VeriSign Trust Network/OU=Terms of use at https://www. ---
http://developer.android.com/training/articles/security-ssl.html
4 of 7
6/2/2014 9:20 PM
TrustManager
java.io.IOException: Hostname 'example.com' was not verified at libcore.net.http.HttpConnection.verifySecureSocketHostname(HttpConnection. at libcore.net.http.HttpsURLConnectionImpl$HttpsEngine.connect(HttpsURLConnec at libcore.net.http.HttpEngine.sendSocketRequest(HttpEngine.java:290) at libcore.net.http.HttpEngine.sendRequest(HttpEngine.java:240) at libcore.net.http.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.j at libcore.net.http.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImp at libcore.net.http.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionI
s_client -connect
HttpsURLConnection
(/reference/javax/net/ssl/HttpsURLConnection.html)
HostnameVerifier
/HostnameVerifier.html)
(/reference/javax/net/ssl
HostnameVerifier
(/reference/javax/net/ssl/HostnameVerifier.html)
URLConnection
(/reference/java/net/URLConnection.html)
http://developer.android.com/training/articles/security-ssl.html
5 of 7
6/2/2014 9:20 PM
// Note that is different than the URL's hostname: // example.com versus example.org HostnameVerifier hostnameVerifier = new HostnameVerifier() { @Override public boolean verify(String hostname, SSLSession session) { HostnameVerifier hv = HttpsURLConnection.getDefaultHostnameVerifier(); return hv.verify("example.com", session); } }; // Tell the URLConnection to use our HostnameVerifier URL url = new URL("https://example.org/"); HttpsURLConnection urlConnection = (HttpsURLConnection)url.openConnection(); urlConnection.setHostnameVerifier(hostnameVerifier); InputStream in = urlConnection.getInputStream(); copyInputStreamToOutputStream(in, System.out);
HttpsURLConnection
/HttpsURLConnection.html)
(/reference/javax/net/ssl
SSLSocket
(/reference/javax/net/ssl/SSLSocket.html) (/reference/javax/net/ssl/HttpsURLConnection.html)
HttpsURLConnection
SSLSocket
(/reference/javax/net/ssl/SSLSocket.html) /net/ssl/TrustManager.html) /HttpsURLConnection.html)
TrustManager HttpsURLConnection
(/reference/javax
(/reference/javax/net/ssl
SSLSocketFactory TrustManager
(/reference/javax/net/ssl/SSLSocketFactory.html)
(/reference/javax/net/ssl/TrustManager.html)
SSLSocket
(/reference/javax/net/ssl/SSLSocket.html) (/reference/javax/net/ssl/SSLSocketFactory.html)
SSLSocketFactory
SSLSocket
(/reference/javax/net/ssl/SSLSocket.html)
SSLSocket
(/reference/javax/net/ssl/SSLSocket.html)
getDefaultHostnameVerifier() HostnameVerifier.verify()
(/reference/javax/net/ssl
/HttpsURLConnection.html#getDefaultHostnameVerifier()) (/reference/javax/net/ssl
/HostnameVerifier.html#verify(java.lang.String, javax.net.ssl.SSLSession))
// Open SSLSocket directly to gmail.com SocketFactory sf = SSLSocketFactory.getDefault(); SSLSocket socket = (SSLSocket) sf.createSocket("gmail.com", 443); HostnameVerifier hv = HttpsURLConnection.getDefaultHostnameVerifier();
http://developer.android.com/training/articles/security-ssl.html
6 of 7
6/2/2014 9:20 PM
SSLSession s = socket.getSession(); // Verify that the certicate hostname is for mail.google.com // This is due to lack of SNI support in the current SSLSocket. if (!hv.verify("mail.google.com", s)) { throw new SSLHandshakeException("Expected mail.google.com, " "found " + s.getPeerPrincipal()); } // At this point SSLSocket performed certificate verificaiton and // we have performed hostname verification, so it is safe to proceed. // ... use socket ... socket.close();
TrustManager
/net/ssl/TrustManager.html) /net/ssl/KeyManager.html) /HttpsURLConnection.html)
(/reference/javax (/reference/javax
KeyManager HttpsURLConnection
(/reference/javax/net/ssl
http://developer.android.com/training/articles/security-ssl.html
7 of 7