We wrote client application in android which connects with https servers using HttpsUrlConnection apis. Due to Poodle vulnerability, we need to disable SSLv3 from the list of enabled protocols while invoking any request.
We followed the guidelines captured by oracle as http://www.oracle.com/technetwork/java/javase/documentation/cve-2014-3566-2342133.html
and added following line before invoking url connection
java.lang.System.setProperty("https.protocols", "TLSv1");
This solution works fine with normal java program. We got SSLHandShakeException when tried to connect with a server which only works on SSLv3 protocol.
But concern is : same fix does not work for android. Am I missing something or should I try another approach for android? Please suggest.
I found the solution for it by analyzing the data packets using wireshark. What I found is that while making a secure connection, android was falling back to SSLv3 from TLSv1 . It is a bug in android versions < 4.4 , and it can be solved by removing the SSLv3 protocol from Enabled Protocols list. I made a custom socketFactory class called NoSSLv3SocketFactory.java. Use this to make a socketfactory.
Use this class like this while connecting :
UPDATE :
Now, correct solution would be to install a newer security provider using Google Play Services:
This effectively gives your app access to a newer version of OpenSSL and Java Security Provider, which includes support for TLSv1.2 in SSLEngine. Once the new provider is installed, you can create an SSLEngine which supports SSLv3, TLSv1, TLSv1.1 and TLSv1.2 the usual way:
Or you can restrict the enabled protocols using
engine.setEnabledProtocols
.Don't forget to add the following dependency (latest version found here):
For more info, checkout this link.
Actually we don't need to disable the SSLV3 or TLSV1.0, What we just need to enable TLSV1.1 or TLSv1.2 in android < 5 devices.
The problem is TLSv1.1 and TLSv1.2 not enabled on Android <5 by default and to connect using these latest secure protocol we must have to enable in Android <5 devices.
This solution fixed my problem : https://stackoverflow.com/a/45853669/3448003
At first I tried Bhavit S. Sengar's answer and it worked for most cases. But sometimes there where issues even when SSLv3 protocol was removed from Enabled Protocols on an Android 4.4.4 device. So the NetCipher library by Hans-Christoph Steiner is perfect to solve that problem as far as I could test it.
We use jsoup to make a bunch of web scraping on different servers, so we cannot set
HttpsURLConnection connection = NetCipher.getHttpsURLConnection(sourceUrl);
. I assume that's the same problem if you use OkHttp.The best solution we've come to is to set the
info.guardianproject.netcipher.client.TlsOnlySocketFactory
from NetCipher asDefaultSSLSocketFactory
in a static block. So it's set for the whole runtime of our app:If you like to inspect the full details (with
trustAllCertificates
) you can do it here.Using PlayService publisher client libraries running on Android I experienced the same problem when running the sample.
Fixed it with @bhavit-s-sengar's awnser above. Had to also change
AndroidPublisherHelper.newTrustedTransport()
to this:Inspired by Bhavit S. Sengar's answer, it bundled that technique into a dead simple method call. You can use the NetCipher library to get a modern TLS config when using Android's
HttpsURLConnection
. NetCipher configures theHttpsURLConnection
instance to use the best supported TLS version, removes SSLv3 support, and configures the best suite of ciphers for that TLS version. First, add it to your build.gradle:Or you can download the netcipher-1.2.jar and include it directly in your app. Then instead of calling:
Call this:
use this code snippet, if server is SSLv3 enable then it will fail handshaking.