Posted on Leave a comment

HttpURLConnection TLS TLSv1.1 TLSv1.2 SSL SSLv3 SSL pinning

What is TLS?

How to Securely Implement TLS Certificate Checking in Android Apps
01.2022 [https://www.guardsquare.com/blog/how-to-securely-implement-tls-certificate-checking-in-android-apps]

An Update on Android TLS Adoption
02 December 2019 [https://android-developers.googleblog.com/2019/12/an-update-on-android-tls-adoption.html]

TLS version depends on android API level

Java Cryptography Architecture Standard Algorithm Name Documentation for JDK 8

square/okhttp and tls 1.2

javax.net.ssl

Security with HTTPS and SSL

OpenSSL

Default configuration for different Android versions:

SSLContext

Algorithm Supported API Levels
Default 10+
SSL 10+
SSLv3 10-25
TLS 1+
TLSv1 10+
TLSv1.1 16+
TLSv1.2 16+

SSLEngine.

Protocol Supported (API Levels) Enabled by default (API Levels)
SSLv3 1–TBD 1–22
TLSv1 1+ 1+
TLSv1.1 20+ 20+
TLSv1.2 20+ 20+

SSLSocket

SSLSocket instances obtained from default SSLSocketFactory, SSLServerSocketFactory, and SSLContext are configured as follows:

Client socket:

Protocol Supported (API Levels) Enabled by default (API Levels)
SSLv3 1–TBD 1–22
TLSv1 1+ 1+
TLSv1.1 16+ 20+
TLSv1.2 16+ 20+

Server socket:

Protocol Supported (API Levels) Enabled by default (API Levels)
SSLv3 1–TBD 1–22
TLSv1 1+ 1+
TLSv1.1 16+ 16+
TLSv1.2 16+ 16+

Android 4.1+ enable TLS 1.1 and TLS 1.2

package com.arvifox.ssltlstest;

import java.io.IOException;
import java.net.InetAddress;
import java.net.Socket;

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

public class ArviFoxSSLSocketFactory extends SSLSocketFactory {

    private static final String[] ENABLED_PROTOCOLS = new String[] { "TLSv1.2" };

    private SSLSocketFactory mSslSocketFactory;

    public WalletSSLSocketFactory(SSLSocketFactory sslSocketFactory) {
        super();
        mSslSocketFactory = sslSocketFactory;
    }

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

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

    @Override
    public SSLSocket createSocket(Socket s, String host, int port, boolean autoClose) throws IOException {
        SSLSocket socket = (SSLSocket) mSslSocketFactory.createSocket(s, host, port, autoClose);
        socket.setEnabledProtocols(ENABLED_PROTOCOLS);
        return socket;
    }

    @Override
    public Socket createSocket(String host, int port) throws IOException {
        SSLSocket socket = (SSLSocket) mSslSocketFactory.createSocket(host, port);
        socket.setEnabledProtocols(ENABLED_PROTOCOLS);
        return socket;
    }

    @Override
    public Socket createSocket(String host, int port, InetAddress localHost, int localPort) throws IOException {
        SSLSocket socket = (SSLSocket) mSslSocketFactory.createSocket(host, port, localHost, localPort);
        socket.setEnabledProtocols(ENABLED_PROTOCOLS);
        return socket;
    }

    @Override
    public Socket createSocket(InetAddress host, int port) throws IOException {
        SSLSocket socket = (SSLSocket) mSslSocketFactory.createSocket(host, port);
        socket.setEnabledProtocols(ENABLED_PROTOCOLS);
        return socket;
    }

    @Override
    public Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort)
            throws IOException {
        SSLSocket socket = (SSLSocket) mSslSocketFactory.createSocket(address, port, localAddress, localPort);
        socket.setEnabledProtocols(ENABLED_PROTOCOLS);
        return socket;
    }
}

//***********

public class ConnectionFactory {

    private final SSLSocketFactory mSSLSocketFactory;

    public ConnectionFactory(Context context) {
        mSSLSocketFactory = buildSSLSocketFactory(context);
    }

    public HttpURLConnection getUrlConnection(String surl) throws IOException,
            ConnectorException {
        final URL url = new URL(surl);
        final HttpsURLConnection urlConnection = (HttpsURLConnection) url.openConnection();
        urlConnection.setSSLSocketFactory(mSSLSocketFactory);
        urlConnection.setHostnameVerifier(new HostnameVerifier() {
            @Override
            public boolean verify(String hostname, SSLSession session) {
                return true;
            }
        });
        return urlConnection;
    }

    private SSLSocketFactory buildSSLSocketFactory(Context context) {
        try {
            final KeyStore clientStore = KeyStore.getInstance("PKCS12");

            clientStore.load(context.getResources().openRawResource(R.raw.cert_file), "password".toCharArray());
            final KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
            kmf.init(clientStore, "password".toCharArray());
            final KeyManager[] kms = kmf.getKeyManagers();

            final TrustManager[] trustAllCerts = new TrustManager[]{};

            final SSLContext sslContext = SSLContext.getInstance("TLS");
            sslContext.init(kms, trustAllCerts, new SecureRandom());

            return sslContext.getSocketFactory();
        } catch (KeyStoreException | IOException | CertificateException | NoSuchAlgorithmException | UnrecoverableKeyException | KeyManagementException e) {
            throw new RuntimeException("Build SSLSocketFactory error", e);
        }
    }
}


Certificate and Public Key Pinning

pdf

Self-Signed Certificates with OkHttp – the Right Way

How, and Why, to run a Man-In-The-Middle Attack on Your Own App

How to Prepare Your Android App for a Pentest – Networking Edition [https://infinum.com/the-capsized-eight/how-to-prepare-your-android-app-for-a-pentest]

Certificate Pinning with OkHttp

Объяснение HTTPS на почтовых голубях [ https://habr.com/ru/post/346752/ ]

Храним токены авторизации безопасно [ https://habr.com/ru/post/423753/ ]

Перехват HTTPS-траффика между Android-устройством и внешним сервером [ https://habr.com/ru/company/infopulse/blog/156711/ ]

Configure Fiddler for Android / Google Nexus 7 [ https://docs.telerik.com/fiddler/Configure-Fiddler/Tasks/ConfigureForAndroid ]

Fiddler = удобный сниффер + прокси сервер
05.2021 [https://habr.com/ru/post/554562/]

SSL PINNING: ЗАЩИТА МОБИЛЬНОГО БАНКИНГА НА ANDROID С ПОМОЩЬЮ SSL СЕРТИФИКАТА [ https://www.emaro-ssl.ru/blog/ssl-pinning-for-android/ ]

Android Security: SSL Pinning [ https://medium.com/@appmattus/android-security-ssl-pinning-1db8acb6621e ]

Android – работа с ssl-сертификатами (как организовать передачу данных через HTTPS) [ http://my-it-notes.com/2011/09/how-to-approve-ssl-certificate-on-android/ ]

Авторизация с помощью клиентских SSL сертификатов в IOS и Android [ https://habr.com/ru/post/194530/ ]

SSL certificates formats: pem, crt, cer, der, p12, pkcs, pfx [ https://www.emaro-ssl.ru/blog/convert-ssl-certificate-formats/ ]

okhttp-peer-certificate-extractor [ https://github.com/fabiomsr/okhttp-peer-certificate-extractor/tree/master/src/main/java/org/fabiomsr/peercertificate ]



Certificate pinning in web view android

Android WebViewClient [ https://developer.android.com/reference/android/webkit/WebViewClient.html ]
shouldOverrideUrlLoading method
Give the host application a chance to take control when a URL is about to be loaded in the current WebView. If a WebViewClient is not provided, by default WebView will ask Activity Manager to choose the proper handler for the URL. If a WebViewClient is provided, returning true causes the current WebView to abort loading the URL, while returning false causes the WebView to continue loading the URL as usual.
Note: This method is not called for POST requests.
WebViewClient::shouldOverrideUrlLoading dont catch form interactions with method=”POST” [ https://issuetracker.google.com/issues/36918490 ]

Webview certificate pinning [ https://stackoverflow.com/questions/33932507/webview-certificate-pinning ]

A simple demo app that demonstrates Certificate pinning and scheme/domain whitelisting in Android WebViews [ https://github.com/menjoo/Android-SSL-Pinning-WebViews ]

Network security configuration [ https://developer.android.com/training/articles/security-config ]

openssl x509 -in cert.crt -pubkey -noout | openssl pkey -pubin -outform der | openssl dgst -sha256 -binary | openssl enc -base64

[ https://square.github.io/okhttp/3.x/okhttp/okhttp3/CertificatePinner.html ]

[ https://medium.com/@cVoronin/ssl-pinning-okhttp-%D0%BA%D0%B0%D0%BA-%D0%BF%D0%BE%D0%BB%D1%83%D1%87%D0%B8%D1%82%D1%8C-%D1%85%D1%8D%D1%88-%D1%81%D0%B5%D1%80%D1%82%D0%B8%D1%84%D0%B8%D0%BA%D0%B0%D1%82%D0%B0-af86d2029b17 ]


[https://t.me/paradisecurity/293]

[Forwarded from paradiSEcurity (paradiSEcurityPub)]
Все любят SSL-пиннинг. Или нет?

Наверно, каждый Android-разработчик знает, что такое SSL-пиннинг. Но для новеньких, я все таки сделаю небольшую сноску:

По-умолчанию, устанавливая SSL соединение по протоколу HTTPS, клиент проверяет сертификат сервера по двум пунктам:

⚡️ Что цепочку SSL сертификата можно проследить от Вашего личного SSL сертификата через промежуточные и до корневого сертификата доверенного центра сертификации

⚡️ Что Ваш SSL сертификат соответствует запрошенному имени хоста

Лично я сталкивалась с этой задачей о-очень часто, тк работаю в специфической сфере и поддерживаю безопасность мобильных приложений. Данный вид защиты необходим для того чтобы бороться с распространенным видом атаки на ваше приложение, которая называется MITM (Man in the middle), она направлена на «прослушку» или изменение трафика между двумя узлами (клиентом и сервером). Другими словами, когда клиент подключается к серверу, он на самом деле имеет дело с хакером, и наоборот.

Способы реализации SSL-пиннинга в Android

Реализовать SSL-пиннинг в Android можно несколькими способами, я видела сразу комбинации из них, но, на мой взгляд, перегружать свой код этим не стоит, тк в таком случае вы рискуете допустить глупую ошибку, которая может залочить ваше приложение. В целом, все эти варианты подробно описаны на Android Developers (https://developer.android.com/).

🔥 С помощью TrustManager (https://developer.android.com/training/articles/security-ssl#UnknownCa)

🔥 Network Security Configuration (https://developer.android.com/training/articles/security-config#:~:text=The%20Network%20Security%20Configuration%20feature,and%20for%20a%20specific%20app)

🔥 OkHttp и CertificatePinner (https://square.github.io/okhttp/4.x/okhttp/okhttp3/-certificate-pinner/)

🔥 Pinning c Retrofit (Настроить так же просто, как и OkHttpClient, тк Retrofit – это фактически надстройка поверх OkHttp)

Все это, конечно, замечательно, но не стоит забывать и о минусах

Например, допустимость внесения изменений снижается. После внедрения SSL-сертификата в код приложения, изменить его уже не так просто. Каждый раз изменяя SSL-сертификат, вам нужно будет выпускать обновление приложения, запускать его на Google Play и молиться, что пользователи его установят. Собственно, поэтому многие отказываются от этого вида защиты. Так что изначально учитывайте специфику вашего приложения и процессов разработки. Выход из этой ситуации – заказать SSL-сертификат на максимальный срок действия в три года, тогда вам не придется делать это слишком часто.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.