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

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

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

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

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

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

Ответ 1

Начиная с Android 4.0, теперь это возможно. Я легко мог установить сертификат прокси-сервера Charles Web Debbuging Proxy на моем ненагруженном устройстве и успешно обнюхать трафик SSL.

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

Перед Android версии 4.0 с версией Android Gingerbread и Froyo был доступен только один файл (/system/etc/security/cacerts.bks), содержащий хранилище доверенных сертификатов со всеми сертификатами CA ('system'), доверенными по умолчанию на 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/security/'как отдельные файлы. Тем не менее, пользователи теперь могут легко добавлять свои собственные "пользовательские" сертификаты, которые будут храниться в "/data/misc/keychain/certs-added".

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

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

Ответ 2

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

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

Ответ 3

Если вам нужен ваш сертификат для соединений 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);
        }
    }
}

Ответ 4

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

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

В основном вам нужно:

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

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

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

  • Измените файл cacerts.bks на своем компьютере, используя поставщик BouncyCastle

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

Ниже приведено более подробное поэтапное обновление предыдущих телефонов Android: Как обновить хранилище ключей сертификата безопасности HTTPS на устройстве pre-android-4.0

Ответ 5

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

Я скопировал /system/etc/security/cacerts.bks на мою sdcard

Скачан http://www.startssl.com/certs/ca.crt и http://www.startssl.com/certs/sub.class1.server.ca.crt

Перешел на portecle.sourceforge.net и выполнил portecle непосредственно с веб-страницы.

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

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

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

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

Ответ 6

Для этого существует более простое решение, чем здесь, или в связанных потоках. Если вы используете веб-просмотр (как и я), вы можете добиться этого, выполнив в нем функцию JAVASCRIPT. Если вы не используете веб-просмотр, вы можете создать скрытую для этой цели. Здесь функция, которая работает практически в любом браузере (или веб-просмотре), чтобы начать установку (как правило, через общий репозиторий сертификатов 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;
}

UPDATE:

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

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

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

Ответ 7

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

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