Прикрепление SSL-сертификата Android с дооснащением

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

Что у меня есть:-

  1. Файл сертификата типа .cert.
  2. .key тип ключевого файла, в котором хранится закрытый ключ.

У меня нет доменного имени, на котором будет реализован этот сертификат. У меня только IP-адрес. Я использую okHttp и модернизирую свой проект. Я видел много примеров переполнения стека, чтобы реализовать это.

Но я не получаю некоторых вещей: - 1. Если у меня нет доменного имени, можно ли использовать ssl в IP-адресе? 2. что будет в поле pins, у меня нет приватного ключа. где я найду закрытый ключ (sha256 / XXXXXXXXXX)?

Retrofit provideRetrofit(OkHttpClient okHttpClient, Gson gson) {
    CertificatePinner certPinner = new CertificatePinner.Builder()
            .add("patternField","pins")
            .build();

       OkHttpClient okHttpClientForPinning = new OkHttpClient.Builder()
            .certificatePinner(certPinner)
            .build();
    OkHttpClient.Builder clientBuilder = new OkHttpClient.Builder();
    try {
       clientBuilder.sslSocketFactory(getSSLConfig(context).getSocketFactory());
    }
    catch (Exception e) {
        e.printStackTrace();
    }

    clientBuilder.hostnameVerifier(new HostnameVerifier() {
        @Override
        public boolean verify(String hostname, SSLSession session) {
            boolean value = true;
            //TODO:Some logic to verify your host and set value
            return value;
        }
    });

    return new Retrofit.Builder()
            .baseUrl(backendUrl)
            .client(okHttpClient)                      
            .client(okHttpClientForPinning)
            .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
            .addConverterFactory(GsonConverterFactory.create(gson))
            .build();


}

person Saurabh Tripathi    schedule 30.07.2019    source источник


Ответы (1)


Значок сертификата

У меня нет доменного имени, на котором будет реализован этот сертификат. У меня только IP-адрес.

Чтобы получить PIN-код для сертификата сервера по IP-адресу, вы можете попробовать этот сценарий bash:

#!/bin/bash
# Heavily inspired on:
#   * https://medium.com/@appmattus/android-security-ssl-pinning-1db8acb6621e#ecea

set -eu

Main()
{
    local domain="${1? Missing domain name to extract and hash the certificate public key !!!}"

    local domain="${domain##*://}"

    local certs=$( openssl s_client -servername "${domain}" -host "${domain}" -port 443 -showcerts </dev/null 2>/dev/null | sed -n '/Certificate chain/,/Server certificate/p' )

    local rest=$certs

    while [[ "$rest" =~ '-----BEGIN CERTIFICATE-----' ]]; do

        cert="${rest%%-----END CERTIFICATE-----*}-----END CERTIFICATE-----"
        rest=${rest#*-----END CERTIFICATE-----}

        local certificate_name="$( echo "$cert" | grep 's:' | sed 's/.*s:\(.*\)/\1/' )"

        if [ -n "${certificate_name}" ]; then
            printf "\nCERTIFICATE NAME:\n\n${certificate_name} \n\n"
        fi

        printf "\nCERTIFICATE PUBLIC KEY HASH:\n\n"

        echo "$cert" |
            openssl x509 -pubkey -noout |
            openssl rsa -pubin -outform der 2>/dev/null |
            openssl dgst -sha256 -binary |
            openssl enc -base64

        echo

        exit 0

    done
}

Main ${@}

Сохраните сценарий bash в файл и вызовите его следующим образом:

bash hash-certificate-public-key-from-domain.bash ip-address-here

Реальный пример использования его против моего личного сайта:

╭─exadra37@exadra37-Vostro-470 ~/Developer/Approov/currency-converter-demo  ‹volley-pinning-with-approov_cleanup-proguard*› 
╰─➤  ./bin/hash-certificate-public-key-from-domain.bash 68.183.252.187                                                                                                                                       130 ↵

CERTIFICATE NAME:

CN = exadra37.com 


CERTIFICATE PUBLIC KEY HASH:

1O0wDRM/roe6UTctDVQ5aN/ASNYsGQFVzXYhO34t5GE=

╭─exadra37@exadra37-Vostro-470 ~/Developer/Approov/currency-converter-demo  ‹volley-pinning-with-approov_cleanup-proguard*› 
╰─➤  ./bin/hash-certificate-public-key-from-domain.bash exadra37.com  

CERTIFICATE NAME:

CN = exadra37.com 


CERTIFICATE PUBLIC KEY HASH:

1O0wDRM/roe6UTctDVQ5aN/ASNYsGQFVzXYhO34t5GE=

╭─exadra37@exadra37-Vostro-470 ~/Developer/Approov/currency-converter-demo  ‹volley-pinning-with-approov_cleanup-proguard*› 
╰─➤  ./bin/hash-certificate-public-key-from-domain.bash https://exadra37.com

CERTIFICATE NAME:

CN = exadra37.com 


CERTIFICATE PUBLIC KEY HASH:

1O0wDRM/roe6UTctDVQ5aN/ASNYsGQFVzXYhO34t5GE=

Как видите, хеш пина 1O0wDRM/roe6UTctDVQ5aN/ASNYsGQFVzXYhO34t5GE= всегда один и тот же.

  1. что будет в поле pins, у меня нет приватного ключа. где я найду закрытый ключ (sha256 / XXXXXXXXXX)?

Закрытый ключ является частным, поэтому, если вы сможете его найти, вся безопасность будет потеряна, если вы также не контролируете сервер, к которому подключаетесь. В любом случае он вам не нужен для закрепления сертификата, просто прикрепите его к открытому ключу сертификата, сгенерировав его хеш, он же булавку, как это делает приведенный выше сценарий bash.

Итак, sha256, который вы ищете, является выходом для вывода в приведенном выше скрипте, также как в моих примерах 1O0wDRM/roe6UTctDVQ5aN/ASNYsGQFVzXYhO34t5GE=.

Реализация закрепления сертификатов

Хотя я не знаю, как помочь вам с модернизацией, я могу показать вам более простой способ реализации закрепления.

В настоящее время для Android существует более простой способ, и я описываю его в своем сообщении в блоге Защита HTTPS с помощью закрепления сертификата, где вы можете узнать, что это можно сделать, просто добавив PIN-код сертификата в файл конфигурации сетевой безопасности, или, если вам нужно поддерживать уровень API ниже 24, вы можете использовать пакет TrustKit вместе с файлом.

Пример: network_security_config.xml с TrustKit:

<?xml version="1.0" encoding="utf-8"?>
<network-security-config>

    <!-- Official Android N API -->
    <!--https://android-developers.googleblog.com/2016/07/changes-to-trusted-certificate.html-->
    <domain-config>
        <domain>currency-converter-demo.pdm.approov.io</domain>
        <trust-anchors>
            <!--<certificates src="user" />-->
            <certificates src="system" />
        </trust-anchors>
        <pin-set>
            <!-- Pin for: currency-converter-demo.pdm.approov.io -->
            <pin digest="SHA-256">qXHiE7hFX2Kj4ZCtnr8u8yffl8w9CTv6kE0U5j0o1XY=</pin>

            <!-- Backup Pin for: currency-converter-demo.pdm.approov.io -->
            <pin digest="SHA-256">47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=</pin>
        </pin-set>

        <!-- TrustKit Android API -->
        <!-- enforce pinning validation -->
        <trustkit-config enforcePinning="true" disableDefaultReportUri="true">
            <!-- Add a reporting URL for pin validation reports -->
            <report-uri>https://report.domain</report-uri>
        </trustkit-config>
    </domain-config>

</network-security-config>
person Exadra37    schedule 13.09.2019
comment
Я хотел бы узнать у того, кто проголосовал против моего ответа. Не могли бы вы объяснить мне, был ли я неправ? - person Exadra37; 08.06.2020
comment
Ответ частично правильный, но он спросил, как добавить этот вызов в модернизацию. - person Javier; 27.01.2021
comment
И я полностью согласен с этим: While I don't know how to help you with Retrofit I can show you a simpler way of implementing pinning., поэтому я не думаю, что это причина отклонять мой ответ. Код, который я предоставил, может помочь ему понять, что для этого нужно, и его не должно быть так сложно перевести на Retrofit. В лучшем случае не голосуйте за него. - person Exadra37; 28.01.2021
comment
@ Exadra37 с этим подходом, когда истечет срок действия хэша SHA256, вам придется обновить приложение, и это повлияет на пользователей, использующих старую версию приложения. Любое решение для этого? - person Ankush Kapoor; 17.05.2021
comment
Срок действия хэша не истекает, но срок действия сертификатов, из которых вы их извлекаете, истекает. Если вы продолжите подписывать сертификат тем же открытым ключом, хеш не изменится, и это не повлияет на пользователей мобильного телефона. Когда вам нужно повернуть пару закрытого / открытого ключей, используемую для подписи сертификатов, вам необходимо заранее запрограммировать ее и использовать хэш для открытого ключа в качестве резервного булавки, которую я упоминаю в комментариях к коду, чтобы избежать блокировки ваших мобильных пользователей в суде. приложение. Другое решение - использовать динамическое закрепление сертификатов, но это очень сложно обеспечить надежно. - person Exadra37; 18.05.2021