Como instalar um certificado CA confiável no dispositivo Android?

134

Criei meu próprio certificado CA e agora quero instalá-lo no meu dispositivo Android Froyo (HTC Desire Z), para que o dispositivo confie no meu certificado.

O Android armazena certificados de CA em seu keystore Java em /system/etc/security/cacerts.bks. Copiei o arquivo para o meu computador, adicionei meu certificado usando o portecle 1.5 e o empurrei de volta para o dispositivo.

Agora, o Android parece não recarregar o arquivo automaticamente. Li em várias postagens de blog que preciso reiniciar o dispositivo. Isso faz com que o arquivo seja substituído pelo original novamente.

Minha próxima tentativa foi instalar o certificado do cartão SD, copiando-o e usando a opção correspondente no menu de configurações. O dispositivo diz que o certificado foi instalado, mas aparentemente não confia no certificado. Além disso, quando tento copiar o keystore para o meu computador, ainda encontro o estoque original cacerts.bks.

Então, qual é a maneira correta de instalar meu próprio certificado de CA raiz em um dispositivo Android 2.2 como um certificado confiável? Existe uma maneira de fazer isso programaticamente?

Björn Marschollek
fonte
Você pode assumir um telefone raiz aqui. :)
Björn Marschollek

Respostas:

116

Antes do Android KitKat, você precisa fazer o root no seu dispositivo para instalar novos certificados.

Do Android KitKat (4.0) até o Nougat (7.0) , é possível e fácil. Consegui instalar o certificado Charles Web Debbuging Proxy no meu dispositivo não-rooteado e detectar com êxito o tráfego SSL.

Extrato de http://wiki.cacert.org/FAQ/ImportRootCert

Antes da versão 4.0 do Android, com a versão Gingerbread & Froyo, havia um único arquivo somente leitura (/system/etc/security/cacerts.bks) contendo o armazenamento confiável com todos os certificados de CA ('sistema') confiáveis ​​por padrão em Android. Os aplicativos do sistema e todos os aplicativos desenvolvidos com o Android SDK usam isso. Siga estas instruções para instalar certificados CAcert no Android Gingerbread, Froyo, ...

A partir do Android 4.0 (Android ICS / 'Ice Cream Sandwich', Android 4.3 'Jelly Bean' e Android 4.4 'KitKat'), os certificados confiáveis ​​do sistema estão na partição do sistema (somente leitura) na pasta '/ system / etc / segurança / 'como arquivos individuais. No entanto, os usuários agora podem adicionar facilmente seus próprios certificados de 'usuário', que serão armazenados em '/ data / misc / keychain / certs-added'.

Os certificados instalados pelo sistema podem ser gerenciados no dispositivo Android na seção Configurações -> Segurança -> Certificados -> 'Sistema', enquanto os certificados confiáveis ​​do usuário são gerenciados na seção 'Usuário'. Ao usar certificados confiáveis ​​do usuário, o Android forçará o usuário do dispositivo Android a implementar medidas de segurança adicionais: o uso de um código PIN, um bloqueio de padrão ou uma senha para desbloquear o dispositivo é obrigatório quando os certificados fornecidos pelo usuário são usados.

A instalação de certificados CAcert como certificados de 'confiança do usuário' é muito fácil. A instalação de novos certificados como certificados 'confiáveis ​​do sistema' exige mais trabalho (e requer acesso root), mas tem a vantagem de evitar o requisito de tela de bloqueio do Android.

A partir do Android N, fica um pouco mais difícil, veja este extrato no site de proxy da Charles :

No Android N, você precisa adicionar configurações ao seu aplicativo para que ele confie nos certificados SSL gerados pelo Charles SSL Proxying. Isso significa que você só pode usar proxy SSL com aplicativos que você controla.

Para configurar seu aplicativo para confiar em Charles, você precisa adicionar um arquivo de configuração de segurança de rede ao seu aplicativo. Esse arquivo pode substituir o padrão do sistema, permitindo que seu aplicativo confie nos certificados de CA instalados pelo usuário (por exemplo, o certificado raiz Charles). Você pode especificar que isso se aplique apenas nas construções de depuração do seu aplicativo, para que as construções de produção usem o perfil de confiança padrão.

Adicione um arquivo res / xml / network_security_config.xml ao seu aplicativo:

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

Em seguida, adicione uma referência a este arquivo no manifesto do seu aplicativo, da seguinte maneira:

<?xml version="1.0" encoding="utf-8"?> 
<manifest>
    <application android:networkSecurityConfig="@xml/network_security_config">
    </application> 
</manifest>
Dean Wild
fonte
1
Meus arquivos de certificado personalizados ( /system/etc/security/cacerts/*.0) não são mantidos após a reinicialização / reinicialização do AVD, portanto, esta solução não teve êxito.
Fikr4n
@BornToCode interessante - eu raramente uso AVD de que eu não estava ciente dessa limitação
Dean selvagem
Eu vejo a configuração debug-overrides, isso significa que essa network_security_configsegmentação é apenas uma variante de depuração? Se eu tiver outra variante como a variante UAT, isso não funcionará?
Isaac
1
@Isaac Isso significa que ele será aplicado a qualquer variantes onde debuggable = true
Dean selvagem
1
@ DeanWild - muito obrigado! Tentei fazer isso funcionar para sempre e continuei recebendo "certificado SSL inválido" ao depurar meu aplicativo. Esta solução funcionou como um encanto para o meu aplicativo em execução Android no Android 9 em um Samsung Nota 8.
Dave Preto
43

Passei muito tempo tentando encontrar uma resposta para isso (preciso do Android para ver os certificados StartSSL). Conclusão: o Android 2.1 e 2.2 permitem importar certificados, mas apenas para uso com WiFi e VPN. Não há interface do usuário para atualizar a lista de certificados raiz confiáveis, mas há discussões sobre como adicionar esse recurso. Não está claro se existe uma solução confiável para atualizar e substituir manualmente o arquivo cacerts.bks.

Detalhes e links: http://www.mcbsys.com/techblog/2010/12/android-certificates/ . Nessa postagem, consulte o link para o bug 11231 do Android - você pode adicionar seu voto e consulta a esse bug.

Mark Berry
fonte
3
Um desenvolvedor do Android respondeu à minha consulta re. atualizando cacerts.bks: "em todas as versões do 2.3, é necessário um OTA para atualizar o cacerts.bks em um telefone não rooteado". code.google.com/p/android/issues/detail?id=11231#c25 . OTA = over-the-air, certo? Pode ser por isso que o seu telefone continua a reverter para o factory cacerts.bks? No entanto, se você tiver acesso root, parece que você poderá fazer o download do código-fonte, adicionar seu certificado e criar cacerts.bks usando o script certimport.sh. android.git.kernel.org/?p=platform/libcore.git;a=tree;f=luni/… .
Mark Berry
Obrigado. Obviamente, essa não era a resposta que eu queria ouvir, mas parece ser a correta. Eu esperava que houvesse uma maneira de instalar um certificado sem atualizar o sistema inteiro. É claro que posso criar o novo cacerts.bks, com acesso root, posso até substituir o antigo, mas ele reverte para a versão original a cada reinicialização. Sem reiniciar, o Android parece se recusar a recarregar o arquivo de certificados confiáveis.
Björn Marschollek
27
Que tal instalar certificados CA nas plataformas 3.X e 4.X?
Alok Kulkarni
1
4.X em diante: stackoverflow.com/questions/4461360/…
Dean Wild
16

Se você precisar do seu certificado para conexões HTTPS, poderá adicionar o arquivo .bks como recurso bruto ao seu aplicativo e estender DefaultHttpConnection para que seus certificados sejam usados ​​para conexões 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);
        }
    }
}
Alexander Egger
fonte
Obrigado pela sua resposta. Na verdade, preciso instalar o certificado de forma que todos os aplicativos no dispositivo confiem no certificado. O mesmo problema também deve existir para algumas CAs menores, como CAcert, cujos certificados não são confiáveis ​​por padrão. Como eles obtêm seus certificados instalados?
Björn Marschollek
Você tentou: Configurações -> Segurança -> Instalar do cartão SD
Alexander Egger
Também isso pode ser interessante: android.git.kernel.org/?p=platform/packages/apps/…
Alexander Egger
2
Tenho o mesmo problema, tenho que carregar um certificado .PDX X509 usando o aplicativo Adroid 2.3.3 e, em seguida, criar uma conexão SSL. Alguém pode me ajudar com o código comentado?
AndroidLearner
9

O guia vinculado aqui provavelmente responderá à pergunta original sem a necessidade de programar um conector SSL personalizado.

Encontrei um guia de instruções muito detalhado sobre a importação de certificados raiz que realmente o orienta na instalação de certificados CA confiáveis ​​em diferentes versões de dispositivos Android (entre outros dispositivos).

Basicamente, você precisará:

  1. Download: o arquivo cacerts.bks do seu telefone.

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

  2. Faça o download do arquivo .crt da autoridade de certificação que você deseja permitir.

  3. Modifique o arquivo cacerts.bks no seu computador usando o BouncyCastle Provider

  4. Faça o upload do arquivo cacerts.bks de volta para o seu telefone e reinicie.

Aqui está um passo a passo mais detalhado para atualizar os telefones Android anteriores: Como atualizar o keystore da autoridade de certificação de segurança HTTPS no dispositivo pré-Android-4.0

RightHandedMonkey
fonte
5

Existe uma solução MUITO mais fácil para isso do que postada aqui ou em tópicos relacionados. Se você estiver usando uma visualização na web (como eu sou), poderá conseguir isso executando uma função JAVASCRIPT nela. Se você não estiver usando uma visualização na web, convém criar uma oculta para esse fim. Aqui está uma função que funciona em praticamente qualquer navegador (ou webview) para iniciar a instalação da CA (geralmente através do repositório OS cert compartilhado, inclusive em um Droid). Ele usa um bom truque com os iFrames. Apenas passe o URL para um arquivo .crt para esta função:

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;
}

ATUALIZAR:

O truque iframe funciona em Droids com API 19 e superior, mas versões mais antigas da visualização na web não funcionam assim. A idéia geral ainda funciona - basta fazer o download / abrir o arquivo com uma visualização na web e deixar o SO assumir o controle. Esta pode ser uma solução mais fácil e mais universal (no java atual agora):

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

Observe que instance_ é uma referência à atividade. Isso funciona perfeitamente se você souber o URL do certificado. No meu caso, no entanto, resolvo isso dinamicamente com o software do servidor. Eu tive que adicionar uma quantidade razoável de código adicional para interceptar um URL de redirecionamento e chamar isso de uma maneira que não causasse uma falha com base em uma complicação de segmentação, mas não adicionarei toda essa confusão aqui ...

BuvinJ
fonte
3

O que eu fiz para o beable usar certificados openssl foi bastante fácil. (no meu telefone raiz)

Copiei /system/etc/security/cacerts.bks para o meu sdcard

Transferido por http://www.startssl.com/certs/ca.crt e http://www.startssl.com/certs/sub.class1.server.ca.crt

Foi ao portecle.sourceforge.net e executou o portecle diretamente da página da web.

Abri meu arquivo cacerts.bks do meu sdcard (nada foi inserido quando solicitada uma senha)

Escolha importar no portacle e abra sub.class1.server.ca.crt, no meu caso, ele já tinha o ca.crt, mas talvez você precise instalá-lo também.

Salvei o keystore e o copiei baxck para /system/etc/security/cacerts.bks (fiz um backup desse arquivo primeiro, apenas por precaução)

Reiniciei meu telefone e agora posso visitar meu site usando um certificado openssl sem erros.

Hans
fonte
alguma idéia de como colocar o cacert.bks de volta em um dispositivo não raiz?
22417 Bob
1

Essas etapas funcionaram para mim:

  1. Instale o aplicativo Android Dory Certificate no seu dispositivo móvel: https://play.google.com/store/apps/details?id=io.tempage.dorycert&hl=pt_BR
  2. Conecte o dispositivo móvel ao laptop com o cabo USB.
  3. Crie uma pasta raiz na memória do telefone interno, copie o arquivo de certificado nessa pasta e desconecte o cabo.
  4. Abra o aplicativo Android Dory Certificate, clique no botão redondo [+] e selecione a opção correta Importar certificado de arquivo.
  5. Selecione o formato, forneça um nome (digitei o mesmo nome do arquivo), procure o arquivo de certificado e clique em [OK].
  6. Três cartas serão listadas. Ignorei o cartão que tinha apenas o botão [SIGN CSR] e continuei a clicar no botão [INSTALL] nos outros dois cartões.
  7. Atualizei o aplicativo Web do PWA, que não havia aberto meu Chrome móvel (ele está hospedado em um servidor Web IIS local) e pronto! Nenhuma mensagem de aviso do chrome. A fechadura verde estava lá. Estava trabalhando.

Como alternativa, encontrei essas opções que eu não precisava tentar, mas parecia fácil de seguir:

Finalmente, pode não ser relevante, mas, se você deseja criar e configurar um certificado autoassinado (com mkcert) para seu aplicativo PWA (site) hospedado em um servidor Web IIS local, segui esta página:

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

Obrigado e espero que ajude !! :)

Manuel Hernandez
fonte
0

Aqui está uma solução alternativa que realmente adiciona seu certificado à lista interna de certificados padrão: Confiando em todos os certificados usando HttpClient sobre HTTPS

No entanto, ele funcionará apenas para o seu aplicativo. Não há como fazê-lo programaticamente para todos os aplicativos no dispositivo de um usuário, pois isso seria um risco à segurança.

empapar
fonte