1

I have an app that downloads documents from 3rd party sites (to browse offline).

I am using a standard HttpUrlConnection.

It used to work like a charm, but since upgrading to Nougat, one of the site produces a very consistent SSLHandshakeException the others are working fine.

I have tries using the new app certificates, no luck. I have even tried the old trick of the "trust all certs" TrustManager. No luck. The TrustManager id not even queries.

I noticed though that this server is using a fairly old cipher.

...
New, TLSv1/SSLv3, Cipher is RC4-MD5
Server public key is 2048 bit
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
SSL-Session:
Protocol  : TLSv1
Cipher    : RC4-MD5
...

Can it be the reason for my woes, and if it is how can I add this cipher to my connection ?

Thx

Edit 1: The app is targetting SDK 22 and compiling against API 22 as well

Edit 2: The code has been hacked a bit to test with a "forced" CA (build with the site's certificate) and to test with the "trust all" trust manager as well. It is to note that, when in use, the "trust all" manager is never used.

SSLContext sslContext = null;

if (testWitCa) {

    Certificate ca = null;
    try {
        ca = cf.generateCertificate(caInput);
        Log.v(this, "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 = SSLContext.getInstance("TLS");
    sslContext.init(null, tmf.getTrustManagers(), null);

} else {

    final TrustManager[] trustAllCerts = new TrustManager[] {
            new X509TrustManager() {
                @Override
                public void checkClientTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException {
                    Log.v(FileDownloader.this, "Checking client with %s", authType);
                }

                @Override
                public void checkServerTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException {
                    Log.v(FileDownloader.this, "Checking server with %s", authType);
                }

                @Override
                public java.security.cert.X509Certificate[] getAcceptedIssuers() {
                    return new java.security.cert.X509Certificate[]{};
                }
            }
    };

    sslContext = SSLContext.getInstance("TLS");
    sslContext.init(null, trustAllCerts, null);
}

URL url = new URL(fromUrl);
HttpURLConnection httpConn;

httpConn = (HttpsURLConnection) url.openConnection();

if (sslContext != null) {
    ((HttpsURLConnection) httpConn).setSSLSocketFactory(sslContext.getSocketFactory());
}

responseCode = httpConn.getResponseCode();

I have tried using the following security config file as well (the root CA for the site the Thawte G3):

<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
    <base-config>
        <trust-anchors>
            <certificates src="@raw/site_ca"/>
            <certificates src="@raw/thawte_g3_ca"/>
            <certificates src="system"/>
        </trust-anchors>
    </base-config>
</network-security-config>
5
  • I guess you're targeting API 24. There are a few changes regarding network security when targeting API 24. I think the easy workaround is targeting API 23. Give it a try and see if it helps. Commented Oct 7, 2016 at 14:27
  • Can you post the code that performs the connection to the site with the crappy cipher? Commented Oct 7, 2016 at 14:29
  • I am experiencing exactly the same issue with an exchange 2007 server. Have you found a solution in the end? Commented Jan 12, 2017 at 11:04
  • Hello. Have you found the fix? Commented Jul 21, 2017 at 13:28
  • @Andigor nope, went another route. Commented Jul 21, 2017 at 15:42

3 Answers 3

1

Same thing on Nexus 6 updated to Nougat. My application worked and now doesn't work anymore.

I tried using an alternative libary (OkHttp) but it ends up in the same result. javax.net.ssl.SSLHandshakeException: Connection closed by peer

The app work against other servers but not this particular one (same cipher parameters as your).

Same app on older Android (6 and below) works great. It doesn't matter if you build for an older version. It crashs on 7.

Something has changed on the SSL stack.

Regards

Sign up to request clarification or add additional context in comments.

1 Comment

yep, this is a bummer... On a side note, the Android HttpUrlConnection is based on Okhttp, so this is normal that it gives you the same results.
0

Use Net Cipher Library for Android to get through this.

HttpUrlConnection connection = NetCipher.getHttpsURLConnection(url);

Gradle Dependency

compile 'info.guardianproject.netcipher:netcipher:1.2'

Comments

0

Android changes its ssl library which they were using in earlier versions named openssl library. But in nougat they have replaced openssl with their own library named boringssl. May be bacause of that you are getting issues.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.