Project

General

Profile

Feature #72

Disable SSLv3 for API 19 (KitKat)

Added by Soren Stoutner about 3 years ago. Updated 10 months ago.

Status:
Closed
Priority:
Next Release
Start date:
11/14/2016
Due date:
% Done:

0%

Estimated time:

History

#1

Updated by Soren Stoutner about 3 years ago

We also want to disable the following ciphers:

TLS_ECDHE_RSA_WITH_RC4_128_SHA
TLS_ECDHE_ECDSA_WITH_RC4_128_SHA
TLS_RSA_WITH_RC4_128_SHA
TLS_RSA_WITH_RC4_128_MD5

#2

Updated by Soren Stoutner about 3 years ago

  • Subject changed from Disable SSLv3 for KitKat (API 19) to Disable SSLv3 for API 19 (KitKat)
  • Description updated (diff)
#3

Updated by Soren Stoutner about 3 years ago

It turns out this is more difficult than expected. It would require creating a custom `SSLSocketFactory` and then applying it to a custom `DefaultHTTPClient`, which would then require using manual HTTP get, post, and head commands and manually processing all responses instead of using WebView's builtin commands. It would be a lot of work, prone to a lot of corner case bugs, for a solution to an old version of Android that will (eventually) go away.

#4

Updated by Soren Stoutner about 3 years ago

An example custom `SSLSocketFactory` is below:

import java.io.IOException;
import java.net.InetAddress;
import java.net.Socket;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;

import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;

public class KitKatSocketFactory extends SSLSocketFactory {
    private SSLSocketFactory sslSocketFactory;

    public KitKatSocketFactory() throws NoSuchAlgorithmException, KeyManagementException {
        SSLContext sslContext = SSLContext.getInstance("TLSv1.2");

        // The first `null` is the `KeyManager`, the second `null` is the `TrustManager`, and the third `null` is `SecureRandom`.
        sslContext.init(null, null, null);

        sslSocketFactory = sslContext.getSocketFactory();
    }

    private Socket disableSSLv3(Socket socket) {
        if ((socket != null) && (socket instanceof SSLSocket)) {
            String[] originalSocketProtocolsArray = ((SSLSocket) socket).getEnabledProtocols();
            ArrayList<String> newSocketProtocolsArrayList = new ArrayList<>();

            for (String originalSocketProtocolString : originalSocketProtocolsArray) {
                if (!originalSocketProtocolString.contains("SSL")) {
                    newSocketProtocolsArrayList.add(originalSocketProtocolString);
                }
            }

            String[] newSocketProtocolsArray = (String[]) newSocketProtocolsArrayList.toArray();

            ((SSLSocket) socket).setEnabledProtocols(newSocketProtocolsArray);
        }

        return socket;
    }

    @Override
    public String[] getDefaultCipherSuites() {
        return sslSocketFactory.getDefaultCipherSuites();
    }

    @Override
    public String[] getSupportedCipherSuites() {
        return sslSocketFactory.getSupportedCipherSuites();
    }

    @Override
    public Socket createSocket(String host, int port) throws IOException {
        Socket socket = sslSocketFactory.createSocket(host, port);

        return disableSSLv3(socket);
    }

    @Override
    public Socket createSocket(InetAddress host, int port) throws IOException {
        Socket socket = sslSocketFactory.createSocket(host, port);

        return disableSSLv3(socket);
    }

    @Override
    public Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort) throws IOException {
        Socket socket = sslSocketFactory.createSocket(address, port, localAddress, localPort);

        return disableSSLv3(socket);
    }

    @Override
    public Socket createSocket(Socket s, String host, int port, boolean autoClose) throws IOException {
        Socket socket = sslSocketFactory.createSocket(s, host, port, autoClose);

        return disableSSLv3(socket);
    }

    @Override
    public Socket createSocket(String host, int port, InetAddress localAddress, int localPort) throws IOException {
        Socket socket = sslSocketFactory.createSocket(host, port, localAddress, localPort);

        return disableSSLv3(socket);
    }
}
#5

Updated by Soren Stoutner about 3 years ago

  • Status changed from New to 6

I have decided to close this as `Rejected`. The amount of effort needed to implement this is too large to justify the results. Those worried about man-in-the-middle attacks are advised to upgrade to newer versions of Android (Lollipop, Marshmallow, or Nougat).

#6

Updated by Soren Stoutner about 3 years ago

I published a news item about this issue at https://www.stoutner.com/kitkat-security-problems/.

#7

Updated by Soren Stoutner about 2 years ago

  • Status changed from 6 to Closed
#8

Updated by Soren Stoutner 10 months ago

  • Priority changed from 2 to Next Release

Also available in: Atom PDF