it-swarm.com.de

Aktivieren bestimmter SSL-Protokolle mit Android WebViewClient

Meine Anwendung verwendet WebViewClient, um SSL-Verbindungen zum Server herzustellen. Der Server ist so konfiguriert, dass er nur die Protokolle TLSv1.1 und höher akzeptiert.

1) Wie überprüfe ich, welche SSL-Protokolle verwendet werden? A) Unterstützt und b) Standardmäßig aktiviert, wenn Android WebViewClient auf einem Gerät verwendet wird. 
2) Wie aktiviere ich bestimmte SSL-Protokolle für die Android WebViewClient-Instanz, die in meiner Anwendung verwendet wird.

Auf einem der Testgeräte, auf denen Android 4.3 ausgeführt wird, wirft WebViewClient den Callback "onReceivedError" mit der Beschreibung "SSL-Handshake fehlgeschlagen" aus.
Chrome-Protokolle lauten wie folgt:
01-29 15: 58: 00.073 5486 5525 W chrom_net: extern/chrom/net/http/http_stream_factory_impl_job.cc: 865: [0129/155800: WARNUNG: http_stream_factory_impl_job.cc (865)] Zurücksetzen auf SSLv3 wegen Host ist TLS-intolerant: 10.209.126.125:443 01-29 15: 58: 00.083 5486 5525 E chrom_net: external/chrom/net/socket/ssl_client_socket_openssl.cc: 792: [0129/155800: ERROR: ssl_client_socket_openssl. Handshake fehlgeschlagen; zurückgegeben 0, SSL-Fehlercode 5, net_error -107 

Meine Anwendung verwendet auch HttpClient- und HttpsUrlConnection-Klassen zum Einrichten von SSL-Verbindungen. Ich konnte die SSLSocket-API verwenden, um bei Verwendung dieser Klassen bestimmte Protokolle zu aktivieren http://developer.Android.com/reference/javax/net/ssl/SSLSocket.html#setEnabledProtocols(Java.lang.String [])

Ich muss dasselbe mit WebViewClient tun. 

25
user802467

Laut Dokumentation ist es NICHT möglich, TLS 1.0 in WebView in Android <4.3 zu unterstützen. Für Android 4.4 ist es standardmäßig deaktiviert.

Überprüfen Sie diese Tabelle auf Unterstützung für TLS 1.0 in verschiedenen Browsern: https://en.wikipedia.org/wiki/Transport_Layer_Security#Web_browsers

9
M. C.

Wenn Ihre App Google Play-Dienste verwendet oder Sie bereit sind, diese zu verwenden, können Sie auf älteren Telefonen neuere Sicherheitsfunktionen verwenden, indem Sie deren Provider installieren. Es ist einfach zu installieren, nur eine Zeile (plus Ausnahmebehandlung usw.). Sie müssen außerdem Google Play-Services zu Ihrer Gradle-Datei hinzufügen, wenn Sie sie noch nicht haben. ProviderInstaller ist im -base-Paket enthalten.

try {
    ProviderInstaller.installIfNeeded(this);
} catch (GooglePlayServicesRepairableException e) {
     // Fix it
} catch (GooglePlayServicesNotAvailableException e) {
     // Skip it
}

Ein vollständiges Beispiel finden Sie unter "Aktualisieren Ihres Sicherheitsanbieters zum Schutz vor SSL-Exploits" von Google.

2
iagreen

Eigentlich habe ich es geschafft, damit es funktioniert, aber Sie benötigen die okHttp-Bibliothek dafür.

    WebViewClient client = new WebViewClient() {
        private OkHttpClient okHttp = new OkHttpClient.Builder().build();

        @Override
        public WebResourceResponse shouldInterceptRequest(WebView view, String url) {
            Request okHttpRequest = new Request.Builder().url(url).build();
            try {
                Response response = okHttp.newCall(okHttpRequest).execute();
                return new WebResourceResponse(response.header("Content-Type", "plain/text"), response.header("Content-Encoding", "deflate"), response.body().byteStream());
            } catch (IOException e) {
                e.printStackTrace();
            }
            return null;
        }
    };
    webView.setWebViewClient(client);

Außerdem benötigen Sie den klassischen Trust Manager Manipulator, die SSL-Socket-Factory und ihre Implementierung in Ihrer Application-Klasse:

public class TrustManagerManipulator implements X509TrustManager {


    private static TrustManager[] trustManagers;
    private static final X509Certificate[] acceptedIssuers = new X509Certificate[] {};

    public boolean isClientTrusted(X509Certificate[] chain) {
        return true;
    }

    public boolean isServerTrusted(X509Certificate[] chain) {
        return true;
    }

    public static void allowAllSSL()
    {

        HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() {
            public boolean verify(String hostname, SSLSession session) {
                return true;
            }
        });
        SSLContext context = null;
        if (trustManagers == null) {
            trustManagers = new TrustManager[] { new TrustManagerManipulator() };
        }
        try {
            context = SSLContext.getInstance("TLS");
            context.init(null, trustManagers, new SecureRandom());
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (KeyManagementException e) {
            e.printStackTrace();
        }
        HttpsURLConnection.setDefaultSSLSocketFactory(context
                .getSocketFactory());
    }

    public void checkClientTrusted(X509Certificate[] chain, String authType)
            throws CertificateException {
    }

    public void checkServerTrusted(X509Certificate[] chain, String authType)
            throws CertificateException {
    }

    public X509Certificate[] getAcceptedIssuers() {
        return acceptedIssuers;
    }
}

SSl Socket Factory:

public class TLSSocketFactory extends SSLSocketFactory {

    private SSLSocketFactory internalSSLSocketFactory;

    public TLSSocketFactory() throws KeyManagementException, NoSuchAlgorithmException {
        SSLContext context = SSLContext.getInstance("TLS");
        TrustManager[] managers = new TrustManager[] { new TrustManagerManipulator() };
        context.init(null, managers, new SecureRandom());
        internalSSLSocketFactory = context.getSocketFactory();
    }

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

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

    @Override
    public Socket createSocket(Socket s, String Host, int port, boolean autoClose) throws IOException {
        return enableTLSOnSocket(internalSSLSocketFactory.createSocket(s, Host, port, autoClose));
    }

    @Override
    public Socket createSocket(String Host, int port) throws IOException, UnknownHostException {
        return enableTLSOnSocket(internalSSLSocketFactory.createSocket(Host, port));
    }

    @Override
    public Socket createSocket(String Host, int port, InetAddress localHost, int localPort) throws IOException, UnknownHostException {
        return enableTLSOnSocket(internalSSLSocketFactory.createSocket(Host, port, localHost, localPort));
    }

    @Override
    public Socket createSocket(InetAddress Host, int port) throws IOException {
        return enableTLSOnSocket(internalSSLSocketFactory.createSocket(Host, port));
    }

    @Override
    public Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort) throws IOException {
        return enableTLSOnSocket(internalSSLSocketFactory.createSocket(address, port, localAddress, localPort));
    }

    private Socket enableTLSOnSocket(Socket socket) {
        if(socket != null && (socket instanceof SSLSocket)) {
            ((SSLSocket)socket).setEnabledProtocols(new String[] {"TLSv1.1", "TLSv1.2"});
        }
        return socket;
    }
}

App-Klasse:

public class App extends Application {
    private static App appInstance;

    @Override
    public void onCreate() {
        super.onCreate();

        setupSSLconnections();
    }

    private void setupSSLconnections() {
        try {
            HttpsURLConnection.setDefaultSSLSocketFactory(new TLSSocketFactory());
        } catch (KeyManagementException | NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
    }
}
2
Alex

es ist nicht möglich, dass Android 4.3 TSL 1.1 nicht unterstützt, aber nur TSL1.0read. Lesen Sie diesen Artikel https://www.ssllabs.com/ssltest/clients.html Find Android 4.3 wird es sehen 

Protokolle TLS 1.3 Nein TLS 1.2 Nein TLS 1.1 Nein TLS 1.0 Ja SSL 3 INSECURE Ja SSL 2 Nein

0
lemon