Вопрос по android-intent, x509certificate, android, android-wifi – как программно установить сертификат CA на Android без участия пользователя

17

Я пытаюсь установить сертификаты без запроса пользователя. Я знаю, что это не очень хорошая практика, но это то, что хочет PM.

С помощьюKeyChain.createInstallIntent()Я могу заставить Android запустить диалог установки сертификата, позвонивstartActivity, Однако, когда я передаю намерениеsendBroadcast, Ничего не произошло. Может быть, платформа не поддерживает это по соображениям безопасности?

String CERT_FILE = Environment.getExternalStorageDirectory() + "/test/IAT.crt";
Intent intent = KeyChain.createInstallIntent();
try {
    FileInputStream certIs = new FileInputStream(CERT_FILE);
    byte [] cert = new byte[(int)certFile.length()];
    certIs.read(cert);
    X509Certificate x509 = X509Certificate.getInstance(cert);
    intent.putExtra(KeyChain.EXTRA_CERTIFICATE, x509.getEncoded()); 
    intent.putExtra(KeyChain.EXTRA_NAME, "IAT Cert");
    EapActivity.this.startActivityForResult(intent, 0);  // this works but shows UI
    EapActivity.this.sendBroadcast(intent);  // this doesn't install cert
} catch (IOException e) {
Нет получателя, который слушал бы этоIntent - просто деятельность в системе, и по уважительным причинам - позволить любому вредоносному случайному приложению автоматически установить корневой CA - это огромная дыра в безопасности. Jens

Ваш Ответ

6   ответов
0

На основе@ospiderОтвет, мне удалось успешно установить сертификат следующим образом:

adb shell mkdir -p /data/misc/user/0/cacerts-added
adb push certificate.cer /data/misc/user/0/cacerts-added/807e3b02.0

# Maybe these two lines are not strictly necessary...
adb shell chmod 644 /data/misc/user/0/cacerts-added/807e3b02.0
adb shell chown system:system /data/misc/user/0/cacerts-added/807e3b02.0

Я получил имя скопированного файла (807e3b02.0) установив вручную сертификат, который я хотел автоматизировать и увидев, как Android сохранил его (сadb shell ls -l /data/misc/user/0/cacerts-added/)

Надеюсь, это поможет.

С уважением.

8

Using KeyChain.createInstallIntent(), I can get Android to launch the certificate installation dialog by calling startActivity. However, when I pass the intent to sendBroadcast, nothing happens.

Мало если естьIntent объекты, которые вы передадитеstartActivity() будет работать сsendBroadcast(), Они являются независимыми каналами шины квази-сообщений, которая являетсяIntent система.

И, случайно, кто-нибудь знает, как определить намерение установки сертификата? (после ввода пользователем пароля и имени сертификата?) Я не нашел ни одного странного способа проверить, правильно ли установлен мой сертификат безопасности CA. Даже до того, как пользователь ввел пароль для извлечения сертификата, когда я запрашиваю хранилище ключей, сертификат присутствует, поэтому я не могу знать, завершил ли пользователь установку или нет.
2

Если у вас есть привилегия root, вы можете скопировать файл certs в/data/misc/user/0/cacerts-added/

@ Sebasti & # xE1; nRodriguez, какую версию вы использовали?
Версия чего? После моего вопроса мне удалось успешно установить сертификат, скопировав его в/data/misc/user/0/cacerts-added/ с именем, которое, по-видимому, является уникальным и управляется изнутри Android. Я также должен был выполнить chmod и скопировать скопированный сертификат.
Привет. Я пытался сделать это, сначала это казалось работающим, но когда приложение, которое мне нужно настроить, попыталось подключиться к своему серверу, это не удалось из-за проблемы с сертификатом. Есть что-то еще, кроме копирования сертификата в эту папку?
4

Для разработчиков несистемных приложений - простой ответ - это невозможно без взаимодействия с пользователем.

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

Step 1 - Create interface

Создайте новый пакет в вашем проекте:android.securityзатем скопируйтеIKeyChainService.aidl в этот пакет.

Step 2 - Bind to service and install certificate

Действие дает пример того, как установить сертификат CA:

public class KeyChainTest extends Activity {

    private final Object mServiceLock = new Object();
    private IKeyChainService mService;
    private boolean mIsBoundService =false;

    private ServiceConnection mServiceConnection = new ServiceConnection() {
        @Override public void onServiceConnected(ComponentName name, 
                                                    IBinder service) {
            synchronized (mServiceLock) {
                mService = IKeyChainService.Stub.asInterface(service);
                mServiceLock.notifyAll();
                try {

                    byte[] result = YOUR_CA_CERT_AS_BYTE_ARRAY

                    //The next line actually installs the certificate
                    mService.installCaCertificate(result);

                } catch (Exception e) {
                    //EXception handling goes here
                }
            }
        }

        @Override public void onServiceDisconnected(ComponentName name) {
            synchronized (mServiceLock) {
                mService = null;
            }
        }
    };

    private void bindService() {
        mIsBoundService = bindService(new Intent(IKeyChainService.class.getName()),
                mServiceConnection,
                Context.BIND_AUTO_CREATE);
    }

    private void unbindServices() {
        if (mIsBoundService) {
            unbindService(mServiceConnection);
            mIsBoundService = false;
        }
    }

    @Override public void onDestroy () {
        unbindServices();
    }


    @Override
    protected void onStart() {
        super.onStart();
        // Bind to KeyChainService
        bindService();
    }
}

Надеюсь, это кому-то поможет - у меня ушло много времени, чтобы разобраться с этим :)

Это невозможно, пока наше приложение не поделится UID.final String actualPackage = getPackageManager().getNameForUid(getCallingUid()); if (!expectedPackage.equals(actualPackage)) { throw new IllegalStateException(actualPackage); } проверяет звонящего. Не могли бы вы объяснить, как вам удалось обойтись без обмена UID?
@Pankaj - Мы используем системный uid в свойстве sharedUserId Манифеста Android для наших системных приложений, возможно, поэтому мне не нужно было делать это программно, как вы.
1

Только приложение пользователя системы может установить сертификат CA в режиме без вывода сообщений. В Lollipop Google представил API управления сертификатами без вывода сообщений через DevicePolicyManager, но вам придется либо быть владельцем профиля Android-for-Work, либо владельцем устройства.

11

Вы можете устанавливать сертификаты только в автоматическом режиме, если у вас есть системные привилегии. Отображение диалогового окна подтверждения является преднамеренным, поскольку доверие к сертификатам может иметь серьезные последствия - Android может с радостью открывать фишинговые сайты без предупреждения и т. Д. При этом диалог в ICS / JB довольно плохой - он не говорит вам, что сертификат, который вы устанавливаете, и кто его выдал, просто это сертификат CA, что отчасти очевидно.

Таким образом, либо использовать общественностьKeyChain API и использованиеstartActivity() чтобы получить диалоговое окно подтверждения или предварительно подготовить устройства перед обработкой их пользователям.

Обновление: в Android 4.4DevicePolicyManager имеет скрытый API (installCaCert), что позволяет устанавливать сертификаты в режиме без вывода сообщений. Вам нужноMANAGE_CA_CERTIFICATES разрешение, которое являетсяsignature|system, поэтому все еще не выполнимо для установленных пользователем приложений.

installCaCert стало видимым вSDK 21 и, очевидно, доступны для администраторов устройств.
Нечто подобное, однако, если для начала нет пароля / PIN-кода, вы можете установить его на то, что вы хотите. Пароль / PIN-код затем используется для получения мастер-ключа для шифрования закрытых ключей. Сертификаты также шифруются, что не является строго обязательным.
Владелец устройства - новый для меня. Доступ к системе через NFC - что может пойти не так? ;-)
Это также вынуждает вас защищать ваше устройство цифровым PIN-кодом или шаблоном разблокировки для экрана блокировки, что немного раздражает, но понятно с точки зрения безопасности пользователя. Я думаю, они хотят быть уверены, что тот, кто устанавливает сертификат, также будет владельцем устройства.
@RupertRawnsley AFAIK, он работает только в том случае, если администратор вашего устройства является также владельцем устройства («супер администратор»)

Похожие вопросы