Как установить доверенный сертификат CA на устройстве Android?

134

Я создал свой собственный сертификат CA и теперь хочу установить его на свое устройство Android Froyo (HTC Desire Z), чтобы устройство доверяло моему сертификату.

Android хранит сертификаты CA в своем хранилище ключей Java в /system/etc/security/cacerts.bks. Я скопировал файл на свой компьютер, добавил сертификат с помощью portecle 1.5 и перенес его на устройство.

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

Моей следующей попыткой было установить сертификат с SD-карты, скопировав его и воспользовавшись соответствующей опцией в меню настроек. Устройство сообщает мне, что сертификат установлен, но, видимо, он не доверяет сертификату. Более того, когда я пытаюсь скопировать хранилище ключей на мой компьютер, я все еще нахожу исходный запас cacerts.bks.

Итак, как правильно установить собственный сертификат корневого ЦС на устройстве Android 2.2 в качестве доверенного сертификата? Есть ли способ сделать это программно?

Бьорн Маршоллек
источник
Вы можете предположить, что у вас есть рутированный телефон здесь. :)
Бьорн Маршоллек

Ответы:

116

До Android KitKat вам нужно получить root права на ваше устройство для установки новых сертификатов.

От Android KitKat (4.0) до Nougat (7.0) это возможно и просто. Я смог установить сертификат Charles Web Debbuging Proxy на свое нерутированное устройство и успешно перехватывать SSL-трафик.

Выдержка из http://wiki.cacert.org/FAQ/ImportRootCert

До версии Android 4.0 с версией Android Gingerbread & Froyo существовал единственный файл только для чтения (/system/etc/security/cacerts.bks), содержащий хранилище доверенных сертификатов со всеми сертификатами CA («системы»), которым доверяют по умолчанию при включении Android. Это можно использовать как для системных приложений, так и для всех приложений, разработанных с помощью Android SDK. Используйте эти инструкции по установке сертификатов CAcert на Android Gingerbread, Froyo, ...

Начиная с Android 4.0 (Android ICS / «Ice Cream Sandwich», Android 4.3 «Jelly Bean» и Android 4.4 «KitKat»), системные доверенные сертификаты находятся в системном разделе (только для чтения) в папке '/ system / etc / безопасность / 'как отдельные файлы. Однако пользователи теперь могут легко добавлять свои собственные «пользовательские» сертификаты, которые будут храниться в «/ data / misc / keychain / certs-Added».

Системными сертификатами можно управлять на устройстве Android в разделе «Настройки» -> «Безопасность» -> «Сертификаты» -> «Система», тогда как доверенные сертификаты пользователей находятся в разделе «Пользователь». При использовании пользовательских доверенных сертификатов Android заставит пользователя устройства Android принять дополнительные меры безопасности: использование PIN-кода, блокировки шаблона или пароля для разблокировки устройства обязательно при использовании пользовательских сертификатов.

Установить сертификаты CAcert в качестве пользовательских доверенных сертификатов очень просто. Установка новых сертификатов как системных доверенных сертификатов требует больше работы (и требует корневого доступа), но имеет преимущество в том, что избегает требования блокировки экрана Android.

Начиная с Android N, становится все сложнее, посмотрите на этот фрагмент с сайта прокси Чарльза :

Начиная с Android N, вам нужно добавить конфигурацию в ваше приложение, чтобы оно доверяло SSL-сертификатам, сгенерированным Charles SSL Proxying. Это означает, что вы можете использовать SSL Proxying только с приложениями, которые вы контролируете.

Чтобы настроить ваше приложение на доверие к Чарльзу, вам необходимо добавить в него файл конфигурации сетевой безопасности. Этот файл может переопределить системную настройку по умолчанию, позволяя вашему приложению доверять установленным пользователем сертификатам CA (например, сертификату Charles Root) Вы можете указать, что это применимо только в отладочных сборках вашего приложения, поэтому в производственных сборках используется профиль доверия по умолчанию.

Добавьте файл res / xml / network_security_config.xml в свое приложение:

<network-security-config>    
    <debug-overrides> 
        <trust-anchors> 
            <!-- Trust user added CAs while debuggable only -->
            <certificates src="user" /> 
        </trust-anchors>    
    </debug-overrides>  
</network-security-config>

Затем добавьте ссылку на этот файл в манифест вашего приложения следующим образом:

<?xml version="1.0" encoding="utf-8"?> 
<manifest>
    <application android:networkSecurityConfig="@xml/network_security_config">
    </application> 
</manifest>
Дин Уайлд
источник
1
Мои файлы пользовательских сертификатов ( /system/etc/security/cacerts/*.0) не сохраняются после перезагрузки / перезапуска AVD, поэтому это решение не было успешным.
fikr4n
@BornToCode интересно - я редко использую AVD, поэтому я не знал об этом ограничении
Dean Wild,
Я вижу настройку debug-overrides, означает ли это, что это network_security_configтолько вариант отладки таргетинга? Если у меня есть другой вариант, такой как вариант UAT, то это не будет работать?
Исаак
1
@Isaac это означает, что он будет применяться к любым вариантам, где debuggable = true
Dean Wild,
1
@DeanWild - большое спасибо! Я пытался заставить это работать вечно и продолжал получать «недействительный сертификат ssl» при отладке моего приложения. Это решение сработало как прелесть для моего Android-приложения, работающего на Android 9 на Samsung Note 8.
Дэйв Блэк
43

Я потратил много времени, пытаясь найти ответ на этот вопрос (мне нужен Android, чтобы увидеть сертификаты StartSSL). Вывод: Android 2.1 и 2.2 позволяют импортировать сертификаты, но только для использования с WiFi и VPN. Пользовательский интерфейс для обновления списка доверенных корневых сертификатов отсутствует, но обсуждается вопрос о добавлении этой функции. Неясно, существует ли надежный обходной путь для ручного обновления и замены файла cacerts.bks.

Подробности и ссылки: http://www.mcbsys.com/techblog/2010/12/android-certificates/ . В этом посте см. Ссылку на ошибку Android 11231 - вы можете добавить свой голос и запросить эту ошибку.

Марк Берри
источник
3
Разработчик Android ответил на мой запрос re. обновление cacerts.bks: «во всех выпусках, начиная с 2.3, требуется OTA для обновления cacerts.bks на телефоне без рутирования». code.google.com/p/android/issues/detail?id=11231#c25 . OTA = по воздуху, верно? Может быть, поэтому ваш телефон продолжает возвращаться к заводскому cacerts.bks? Однако, если у вас ДЕЙСТВИТЕЛЬНО есть root-доступ, похоже, вы сможете загрузить исходный код, добавить сертификат, а затем создать cacerts.bks с помощью скрипта certimport.sh. android.git.kernel.org/?p=platform/libcore.git;a=tree;f=luni/… .
Марк Берри,
Спасибо. Очевидно, это был не тот ответ, который я хотел услышать, но, похоже, он правильный. Я надеялся, что есть способ установить сертификат без обновления всей системы. Я, конечно, могу создать новый cacerts.bks, с root-доступом я могу даже заменить старый, но он возвращается к исходной версии при каждой перезагрузке. Без перезагрузки Android вроде бы отказывается перезагружать файл доверенных сертификатов.
Björn Marschollek
27
Как насчет установки сертификатов CA на платформах 3.X и 4.X?
Алок Кулкарни
1
4.X и далее: stackoverflow.com/questions/4461360/…
Dean Wild
16

Если вам нужен сертификат для соединений HTTPS, вы можете добавить файл .bks в качестве необработанного ресурса в свое приложение и расширить DefaultHttpConnection, чтобы ваши сертификаты использовались для соединений HTTPS.

public class MyHttpClient extends DefaultHttpClient {

    private Resources _resources;

    public MyHttpClient(Resources resources) {
        _resources = resources;
    }

    @Override
    protected ClientConnectionManager createClientConnectionManager() {
        SchemeRegistry registry = new SchemeRegistry();
        registry.register(new Scheme("http", PlainSocketFactory
            .getSocketFactory(), 80));
        if (_resources != null) {
            registry.register(new Scheme("https", newSslSocketFactory(), 443));
        } else {
            registry.register(new Scheme("https", SSLSocketFactory
                .getSocketFactory(), 443));
        }
        return new SingleClientConnManager(getParams(), registry);
    }

    private SSLSocketFactory newSslSocketFactory() {
        try {
            KeyStore trusted = KeyStore.getInstance("BKS");
            InputStream in = _resources.openRawResource(R.raw.mystore);
            try {
                trusted.load(in, "pwd".toCharArray());
            } finally {
                in.close();
            }
            return new SSLSocketFactory(trusted);
        } catch (Exception e) {
            throw new AssertionError(e);
        }
    }
}
Александр Эггер
источник
Спасибо за ваш ответ. На самом деле мне нужно установить сертификат таким образом, чтобы каждое приложение на устройстве доверяло сертификату. Та же проблема должна существовать и для некоторых небольших центров сертификации, таких как CAcert, сертификаты которых не являются доверенными по умолчанию. Как они устанавливают свои сертификаты?
Björn Marschollek
Вы пробовали: Настройки -> Безопасность -> Установить с SD-карты
Александр Эггер
Также это может быть интересно: android.git.kernel.org/?p=platform/packages/apps/…
Александр Эггер
2
У меня та же проблема, мне нужно загрузить сертификат .PDX X509 с помощью приложения Adroid 2.3.3, а затем создать SSL-соединение. Может ли кто-нибудь помочь мне с закомментированным кодом?
AndroidLearner
9

Связанное здесь руководство , вероятно, ответит на исходный вопрос без необходимости программирования настраиваемого коннектора SSL.

Нашел очень подробное руководство по импорту корневых сертификатов, которое на самом деле поможет вам установить доверенные сертификаты CA на разные версии устройств Android (среди других устройств).

В основном вам необходимо:

  1. Загрузите: файл cacerts.bks со своего телефона.

    adb pull /system/etc/security/cacerts.bks cacerts.bks

  2. Загрузите файл .crt из удостоверяющего центра, который вы хотите разрешить.

  3. Измените файл cacerts.bks на вашем компьютере с помощью BouncyCastle Provider.

  4. Загрузите файл cacerts.bks обратно на свой телефон и перезагрузитесь.

Вот более подробные пошаговые инструкции по обновлению более ранних версий телефонов Android: Как обновить хранилище ключей центра сертификации безопасности HTTPS на устройстве до версии Android 4.0

RightHandedMonkey
источник
5

Для этого есть НАМНОГО более простое решение, чем опубликованное здесь или в связанных темах. Если вы используете веб-просмотр (как и я), вы можете добиться этого, выполнив в нем функцию JAVASCRIPT. Если вы не используете веб-просмотр, вы можете создать для этой цели скрытый. Вот функция, которая работает практически в любом браузере (или веб-просмотре), чтобы запустить установку CA (обычно через общий репозиторий сертификатов os, в том числе на Droid). Он использует хороший трюк с iFrames. Просто передайте этой функции URL-адрес файла .crt:

function installTrustedRootCert( rootCertUrl ){
    id = "rootCertInstaller";
    iframe = document.getElementById( id );
    if( iframe != null ) document.body.removeChild( iframe );
    iframe = document.createElement( "iframe" );
    iframe.id = id;
    iframe.style.display = "none";
    document.body.appendChild( iframe );
    iframe.src = rootCertUrl;
}

ОБНОВИТЬ:

Трюк с iframe работает на дроидах с API 19 и выше, но старые версии веб-просмотра не будут работать так. Однако общая идея все еще работает - просто загрузите / откройте файл с помощью веб-просмотра, а затем позвольте операционной системе взять на себя управление. Это может быть более простое и универсальное решение (сейчас в реальной java):

 public static void installTrustedRootCert( final String certAddress ){
     WebView certWebView = new WebView( instance_ );
     certWebView.loadUrl( certAddress );
 }

Обратите внимание, что instance_ - это ссылка на Activity. Это отлично работает, если вы знаете URL-адрес сертификата. В моем случае, однако, я решаю это динамически с помощью серверного программного обеспечения. Мне пришлось добавить изрядное количество дополнительного кода, чтобы перехватить URL-адрес перенаправления и вызвать его таким образом, чтобы не вызвать сбоя из-за сложности потоковой передачи, но я не буду добавлять сюда всю эту путаницу ...

BuvinJ
источник
3

Что я сделал, чтобы использовать сертификаты startssl, было довольно просто. (на моем рутированном телефоне)

Я скопировал /system/etc/security/cacerts.bks на свою SD-карту

Загружено http://www.startssl.com/certs/ca.crt и http://www.startssl.com/certs/sub.class1.server.ca.crt

Зашел на portecle.sourceforge.net и запустил portecle прямо с веб-страницы.

Открыл мой файл cacerts.bks с моей SD-карты (ничего не ввел при запросе пароля)

Выберите импорт в портакле и откройте sub.class1.server.ca.crt, в моем случае он уже имел ca.crt, но, возможно, вам также нужно установить его.

Сохранил хранилище ключей и скопировал его baxck в /system/etc/security/cacerts.bks (на всякий случай я сделал резервную копию этого файла)

Перезагрузил свой телефон, и теперь я могу без ошибок заходить на свой сайт, используя сертификат startssl.

ганс
источник
есть идеи, как вернуть cacert.bks на устройство без рутирования?
Боб
1

Эти шаги работали для меня:

  1. Установите приложение Dory Certificate для Android на свое мобильное устройство: https://play.google.com/store/apps/details?id=io.tempage.dorycert&hl=en_US
  2. Подключите мобильное устройство к ноутбуку с помощью USB-кабеля.
  3. Создайте корневую папку во внутренней памяти телефона, скопируйте файл сертификата в эту папку и отсоедините кабель.
  4. Откройте приложение Dory Certificate для Android, нажмите круглую кнопку [+] и выберите правильный вариант «Импортировать сертификат файла».
  5. Выберите формат, укажите имя (я ввел то же, что и имя файла), просмотрите файл сертификата и нажмите [OK].
  6. Появятся три карты. Я проигнорировал карту, на которой была только кнопка [ПОДПИСАТЬ CSR], и щелкнул кнопку [УСТАНОВИТЬ] на двух других картах.
  7. Я обновил веб-приложение PWA, которое я не открывал в своем мобильном Chrome (он размещен на локальном веб-сервере IIS) и вуаля! Нет предупреждающего сообщения о Chrome. Зеленый замок был там. Это было сработало.

В качестве альтернативы я нашел следующие варианты, которые мне не нужно было пробовать самому, но которые выглядели простыми:

Наконец, это может быть неактуальным, но если вы хотите создать и настроить самозаверяющий сертификат (с помощью mkcert) для своего приложения (веб-сайта) PWA, размещенного на локальном веб-сервере IIS, я следил за этой страницей:

https://medium.com/@aweber01/locally-trusted-development-certificates-with-mkcert-and-iis-e09410d92031

Спасибо и надеюсь, что это поможет !! :)

Мануэль Эрнандес
источник
0

Вот альтернативное решение, которое фактически добавляет ваш сертификат во встроенный список сертификатов по умолчанию: Доверять всем сертификатам с помощью HttpClient через HTTPS

Однако это будет работать только для вашего приложения. Невозможно программно сделать это для всех приложений на устройстве пользователя, поскольку это может представлять угрозу безопасности.

emmby
источник
0

Если у вас есть рутированное устройство, вы можете использовать модуль Magisk для перемещения пользовательских сертификатов в систему, чтобы он стал доверенным сертификатом.

https://github.com/yochananmarqos/Move-Certificates

Nightcap79
источник