Закрепление SSL с сетевой библиотекой Volley на Android

Я хочу использовать SSL Pinning в сетевой библиотеке volley. Есть ли способ реализовать закрепление SSL с залпом? Предоставляет ли залп эту поддержку для улучшения безопасности?


person KAPLANDROID    schedule 28.01.2015    source источник
comment
Вы нашли что-нибудь?   -  person Dimillian    schedule 02.02.2015
comment
Основной целью этого является предотвращение MITM? Если злоумышленник может обратно скомпилировать APK и извлечь сертификат, что он действительно мешает?   -  person Takeshi Kaga    schedule 09.09.2019
comment
@TakeshiKaga Я не думаю, что ты прав. Извлечение открытого ключа из приложения не поможет вам провести MITM-атаку, поскольку вам нужен закрытый ключ. Для лучшего понимания проверьте, как работает TLS. Что вы можете сделать, так это перекомпилировать приложение и изменить ключ, но это делает уязвимой только вашу сборку.   -  person Michal Zhradnk Nono3551    schedule 09.09.2020


Ответы (4)


Я просто реализовал это, как описано здесь: http://blog.ostorlab.co/2016/05/ssl-pinning-in-android-networking.html

Вот необходимый код для залповой реализации:

CertificateFactory cf = CertificateFactory.getInstance("X.509");

// Generate the certificate using the certificate file under res/raw/cert.cer
InputStream caInput = new BufferedInputStream(getResources().openRawResource(R.raw.cert));
Certificate ca = cf.generateCertificate(caInput);
caInput.close();

// Create a KeyStore containing our trusted CAs
String keyStoreType = KeyStore.getDefaultType();
KeyStore trusted = KeyStore.getInstance(keyStoreType);
trusted.load(null, null);
trusted.setCertificateEntry("ca", ca);

// Create a TrustManager that trusts the CAs in our KeyStore
String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
tmf.init(trusted);

// Create an SSLContext that uses our TrustManager
SSLContext context = SSLContext.getInstance("TLS");
context.init(null, tmf.getTrustManagers(), null);

SSLSocketFactory sf = context.getSocketFactory();
mRequestQueue = Volley.newRequestQueue(mCtx.getApplicationContext(), new HurlStack(null, sf));

Кажется, работает!

person niggeulimann    schedule 26.04.2017
comment
Он работает в первый/второй раз, показывает исключение SSLHandshake. Однако это не сработает, когда вы повторите попытку, вы успешно получите ответ сети. - person Chandler; 04.05.2021

Я только что изучил то же самое для проекта, над которым я работаю. Однако положение, в котором я нахожусь, может отличаться от вашего.

Я использую Volley со стеком сети OKHttp (https://gist.github.com/JakeWharton/5616899< /а>):

Добавьте их в свою сборку Gradle: 1

compile "com.squareup.okhttp:okhttp:2.7.5"
compile "com.squareup.okhttp:okhttp-urlconnection:2.7.5"

Добавьте класс OKHttpStack;

public class OKHttpStack extends HurlStack {
    private final OkUrlFactory okUrlFactory;
    public OKHttpStack() {

        this(new OkUrlFactory( 
            new OkHttpClient.Builder()
                    .certificatePinner(
                        new CertificatePinner.Builder()
                            .add("example.com", "sha256/afwiKY3RxoMmLkuRW1l7QsPZTJPwDS2pdDROQjXw8ig=") //This is the cert
                            .build())
                    .build();
        ));
    }
    public OKHttpStack(OkUrlFactory okUrlFactory) {
        if (okUrlFactory == null) {
            throw new NullPointerException("Client must not be null.");
        }
        this.okUrlFactory = okUrlFactory;
    }

    @Override
    protected HttpURLConnection createConnection(URL url) throws IOException {
        return okUrlFactory.open(url);
    }
}

Когда вы затем создадите свою RequestQueue, сделайте что-то вроде:

Network network = new BasicNetwork(new OKHttpStack());
File cacheDir = new File(context.getCacheDir(), "volley");
int threads = 4;
mRequestQueue = new RequestQueue(new DiskBasedCache(cacheDir), network, threads);

Обратите внимание, что мне еще предстоит проверить это, мы думаем о закреплении в данный момент.

Удачи! Гав

Использованная литература:

https://gist.github.com/JakeWharton/5616899 https://github.com/square/okhttp/blob/master/samples/guide/src/main/java/okhttp3/recipes/CertificatePinning.java

person Gavin Harris    schedule 05.04.2017
comment
Спасибо, чувак, твое решение спасло меня. Мне пришлось реализовать закрепление ssl на Android версии ниже 24, и у нас есть две библиотеки в нашем приложении, Volley и Ksoap. Я не получал никакой помощи ниоткуда, даже трасткит не работал. Потом я наткнулся на твой сол и принял участие в HurlStack. И пиннинг был доступен залпом в один миг. Чего я не понимаю, так это того, что я создаю клиент okhttp, добавляю к нему пиннер сертификата, а затем этот код mRequestQueue = Volley.newRequestQueue(context, new HurlStack(null, okClien.sslSocketFactory), приложение работает гладко, но закрепление не работало, знаете почему? - person beginner; 20.03.2020
comment
Когда вы создаете свой экземпляр очереди запросов (mRequestQueue), вы передаете ему new HurlStack, а не свой собственный OKHttpStack. Попробуйте отключить создание очереди запросов с помощью чего-то вроде mRequestQueue = Volley.newRequestQueue(context, new OKHttpStack(...)); - person Gavin Harris; 25.03.2020
comment
хорошо, не знал, что мы можем создать экземпляр запроса залпа с помощью okhttpStack. Был ограничен своими знаниями в этом разделе. Мы пробуем это всякий раз, когда я снова сталкиваюсь с подобными вещами. Спасибо :) - person beginner; 01.04.2020
comment
okUrlFactory.open сейчас недоступен, поэтому приложение вылетает. Любое решение для этого? - person Ankush Kapoor; 02.07.2021

Вы можете использовать закрепление открытого ключа вместо закрепления сертификата:

Закрепление открытого ключа с помощью Volley Библиотека

person Faruk Toptas    schedule 04.02.2016
comment
Проблема с HPKP заключается в том, что приложение будет уязвимо при первом подключении к веб-сервису. Если в этот момент злоумышленник сможет выполнить MitM, клиент может быть привязан к неправильному сертификату на очень долгое время. Этого не произойдет, если вы закрепите соединение, используя традиционное закрепление сертификата. - person arnau; 13.01.2017

Я реализую то же самое. Я нашел сообщение в блоге, которое, надеюсь, поможет вам

http://ogrelab.ikratko.com/using-android-volley-with-self-signed-certificate/

person Viet Nguyen    schedule 03.02.2015
comment
Я пробовал это, но есть проблема. Я загружаю пример кода и просто меняю URL-адрес веб-сайта на google.com, и он не выдает никаких ошибок при подключении к Google. .com и получает данные. Ты это видел? - person KAPLANDROID; 24.03.2015
comment
Я попробовал тестовый файл сертификата и свой собственный сертификат, но результат тот же. - person KAPLANDROID; 24.03.2015