Comment installer un certificat CA de confiance sur un appareil Android?

134

J'ai créé mon propre certificat CA et je souhaite maintenant l'installer sur mon appareil Android Froyo (HTC Desire Z), afin que l'appareil fasse confiance à mon certificat.

Android stocke les certificats CA dans son keystore Java au format /system/etc/security/cacerts.bks. J'ai copié le fichier sur mon ordinateur, ajouté mon certificat à l'aide de portecle 1.5 et l' ai repoussé sur l'appareil.

Désormais, Android ne semble pas recharger le fichier automatiquement. J'ai lu dans plusieurs articles de blog que j'ai besoin de redémarrer l'appareil. Cela entraîne à nouveau le remplacement du fichier par le fichier d'origine.

Mon prochain essai a été d'installer le certificat à partir de la carte SD en le copiant et en utilisant l'option correspondante dans le menu des paramètres. L'appareil m'indique que le certificat a été installé, mais apparemment il ne fait pas confiance au certificat. De plus, lorsque j'essaye de copier le keystore sur mon ordinateur, je trouve toujours le stock d'origine cacerts.bks.

Alors, quelle est la bonne façon d'installer mon propre certificat CA racine sur un appareil Android 2.2 en tant que certificat de confiance? Existe-t-il un moyen de le faire par programme?

Björn Marschollek
la source
Vous pouvez supposer un téléphone enraciné ici. :)
Björn Marschollek

Réponses:

116

Avant Android KitKat, vous devez rooter votre appareil pour installer de nouveaux certificats.

Depuis Android KitKat (4.0) jusqu'à Nougat (7.0), c'est possible et facile. J'ai pu installer le certificat Charles Web Debbuging Proxy sur mon appareil non rooté et renifler avec succès le trafic SSL.

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

Avant la version 4.0 d'Android, avec la version Android Gingerbread & Froyo, il y avait un seul fichier en lecture seule (/system/etc/security/cacerts.bks) contenant le magasin de confiance avec tous les certificats CA ('système') approuvés par défaut sur Android. Les applications système et toutes les applications développées avec le SDK Android l'utilisent. Utilisez ces instructions pour installer les certificats CAcert sur Android Gingerbread, Froyo, ...

À partir d'Android 4.0 (Android ICS / 'Ice Cream Sandwich', Android 4.3 'Jelly Bean' et Android 4.4 'KitKat'), les certificats de confiance système se trouvent sur la partition système (en lecture seule) dans le dossier '/ system / etc / security / 'en tant que fichiers individuels. Cependant, les utilisateurs peuvent désormais facilement ajouter leurs propres certificats «utilisateur» qui seront stockés dans «/ data / misc / keychain / certs-added».

Les certificats installés par le système peuvent être gérés sur l'appareil Android dans la section Paramètres -> Sécurité -> Certificats -> 'Système', tandis que les certificats de confiance de l'utilisateur sont gérés dans la section 'Utilisateur'. Lors de l'utilisation de certificats de confiance utilisateur, Android obligera l'utilisateur de l'appareil Android à mettre en œuvre des mesures de sécurité supplémentaires: l'utilisation d'un code PIN, d'un motif de verrouillage ou d'un mot de passe pour déverrouiller l'appareil est obligatoire lorsque des certificats fournis par l'utilisateur sont utilisés.

L'installation de certificats CAcert en tant que certificats «de confiance par l'utilisateur» est très simple. L'installation de nouveaux certificats en tant que certificats de `` confiance système '' nécessite plus de travail (et nécessite un accès root), mais elle a l'avantage d'éviter l'exigence de l'écran de verrouillage Android.

À partir d'Android N, cela devient un peu plus difficile, voir cet extrait du site Web du proxy Charles :

À partir d'Android N, vous devez ajouter une configuration à votre application afin qu'elle fasse confiance aux certificats SSL générés par Charles SSL Proxying. Cela signifie que vous ne pouvez utiliser le proxy SSL qu'avec les applications que vous contrôlez.

Pour configurer votre application pour qu'elle fasse confiance à Charles, vous devez ajouter un fichier de configuration de sécurité réseau à votre application. Ce fichier peut remplacer la valeur par défaut du système, permettant à votre application de faire confiance aux certificats CA installés par l'utilisateur (par exemple le certificat racine Charles). Vous pouvez spécifier que cela s'applique uniquement aux versions de débogage de votre application, afin que les versions de production utilisent le profil d'approbation par défaut.

Ajoutez un fichier res / xml / network_security_config.xml à votre application:

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

Ajoutez ensuite une référence à ce fichier dans le manifeste de votre application, comme suit:

<?xml version="1.0" encoding="utf-8"?> 
<manifest>
    <application android:networkSecurityConfig="@xml/network_security_config">
    </application> 
</manifest>
Dean sauvage
la source
1
Mes fichiers de certificats personnalisés ( /system/etc/security/cacerts/*.0) ne sont pas conservés après le redémarrage / redémarrage d'AVD, donc cette solution n'a pas réussi.
fikr4n le
@BornToCode intéressant - J'utilise rarement AVD, donc je n'étais pas au courant de cette limitation
Dean Wild
Je vois le paramètre debug-overrides, cela signifie-t-il que cette network_security_configvariante de débogage de ciblage uniquement? Si j'ai une autre variante telle que la variante UAT, cela ne fonctionnera pas?
Isaac
1
@Isaac cela signifie qu'il s'appliquera à toutes les variantes où debuggable = true
Dean Wild
1
@DeanWild - merci beaucoup! J'ai essayé de faire fonctionner cela pour toujours et j'ai continué à obtenir un "certificat SSL invalide" lors du débogage de mon application. Cette solution a fonctionné comme un charme pour mon application Android fonctionnant sous Android 9 sur un Samsung Note 8.
Dave Black
43

J'ai passé beaucoup de temps à essayer de trouver une réponse à cela (j'ai besoin d'Android pour voir les certificats StartSSL). Conclusion: Android 2.1 et 2.2 vous permettent d'importer des certificats, mais uniquement pour une utilisation avec WiFi et VPN. Il n'y a pas d'interface utilisateur pour mettre à jour la liste des certificats racine approuvés, mais il y a une discussion sur l'ajout de cette fonctionnalité. On ne sait pas s'il existe une solution de contournement fiable pour mettre à jour et remplacer manuellement le fichier cacerts.bks.

Détails et liens: http://www.mcbsys.com/techblog/2010/12/android-certificates/ . Dans cet article, consultez le lien vers le bogue Android 11231 - vous voudrez peut-être ajouter votre vote et votre requête à ce bogue.

Mark Berry
la source
3
Un développeur Android a répondu à ma requête re. mise à jour de cacerts.bks: "dans toutes les versions de la version 2.3, un OTA est nécessaire pour mettre à jour le cacerts.bks sur un téléphone non rooté." code.google.com/p/android/issues/detail?id=11231#c25 . OTA = over-the-air, non? Serait-ce la raison pour laquelle votre téléphone revient constamment à l'usine cacerts.bks? Cependant, si vous avez un accès root, il semble que vous devriez pouvoir télécharger le code source, ajouter votre certificat, puis créer cacerts.bks en utilisant le script certimport.sh. android.git.kernel.org/?p=platform/libcore.git;a=tree;f=luni/… .
Mark Berry
Merci. Ce n'était évidemment pas la réponse que je voulais entendre, mais cela semble être la bonne. J'espérais qu'il y avait un moyen d'installer un certificat sans mettre à jour tout le système. Je peux bien sûr construire le nouveau cacerts.bks, avec un accès root, je peux même remplacer l'ancien, mais il revient à la version d'origine à chaque redémarrage. Sans redémarrage, Android semble refuser de recharger le fichier de certificats de confiance.
Björn Marschollek
27
Qu'en est-il de l'installation de certificats CA sur les plates-formes 3.X et 4.X?
Alok Kulkarni
1
4.X et suivants: stackoverflow.com/questions/4461360/…
Dean Wild
16

Si vous avez besoin de votre certificat pour les connexions HTTPS, vous pouvez ajouter le fichier .bks en tant que ressource brute à votre application et étendre DefaultHttpConnection afin que vos certificats soient utilisés pour les connexions 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
la source
Merci pour votre réponse. En fait, je dois installer le certificat de manière à ce que chaque application sur l'appareil fasse confiance au certificat. Le même problème devrait également exister pour certaines autorités de certification plus petites comme CAcert, dont les certificats ne sont pas approuvés par défaut. Comment font-ils installer leurs certificats?
Björn Marschollek
Avez-vous essayé: Paramètres -> Sécurité -> Installer à partir de la carte SD
Alexander Egger
Cela pourrait également être intéressant: android.git.kernel.org/?p=platform/packages/apps/...
Alexander Egger
2
J'ai le même problème, je dois charger un certificat .PDX X509 à l'aide de l'application Adroid 2.3.3, puis créer une connexion SSL. Quelqu'un peut-il m'aider avec un code commenté?
AndroidLearner
9

Le guide lié ici répondra probablement à la question initiale sans avoir besoin de programmer un connecteur SSL personnalisé.

Nous avons trouvé un guide pratique très détaillé sur l'importation de certificats racine qui vous guide dans l'installation de certificats CA de confiance sur différentes versions d'appareils Android (entre autres appareils).

En gros, vous devrez:

  1. Téléchargement: le fichier cacerts.bks depuis votre téléphone.

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

  2. Téléchargez le fichier .crt auprès de l'autorité de certification que vous souhaitez autoriser.

  3. Modifiez le fichier cacerts.bks sur votre ordinateur à l'aide du fournisseur BouncyCastle

  4. Téléchargez le fichier cacerts.bks sur votre téléphone et redémarrez.

Voici une étape plus détaillée par étape pour mettre à jour les téléphones Android précédents: Comment mettre à jour le magasin de clés de l'autorité de certification de sécurité HTTPS sur un appareil pré-android-4.0

RightHandedMonkey
la source
5

Il existe une solution BEAUCOUP plus simple à cela que celle publiée ici ou dans les fils connexes. Si vous utilisez une vue Web (comme je le suis), vous pouvez y parvenir en exécutant une fonction JAVASCRIPT en son sein. Si vous n'utilisez pas de vue Web, vous souhaiterez peut-être en créer une masquée à cette fin. Voici une fonction qui fonctionne dans à peu près n'importe quel navigateur (ou vue Web) pour lancer l'installation de CA (généralement via le référentiel de certificats os partagé, y compris sur un Droid). Il utilise une belle astuce avec iFrames. Passez simplement l'url d'un fichier .crt à cette fonction:

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

METTRE À JOUR:

L'astuce iframe fonctionne sur les Droids avec l'API 19 et plus, mais les anciennes versions de la vue Web ne fonctionneront pas comme ça. L'idée générale fonctionne toujours cependant - téléchargez / ouvrez simplement le fichier avec une vue Web, puis laissez le système d'exploitation prendre le relais. Cela peut être une solution plus simple et plus universelle (dans le java actuel maintenant):

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

Notez que instance_ est une référence à l'activité. Cela fonctionne parfaitement si vous connaissez l'URL du cert. Dans mon cas, cependant, je résous cela de manière dynamique avec le logiciel côté serveur. J'ai dû ajouter une bonne quantité de code supplémentaire pour intercepter une URL de redirection et l'appeler d'une manière qui n'a pas causé de crash basé sur une complication de thread, mais je n'ajouterai pas toute cette confusion ici ...

BuvinJ
la source
3

Ce que j'ai fait pour pouvoir utiliser les certificats startssl a été assez simple. (sur mon téléphone enraciné)

J'ai copié /system/etc/security/cacerts.bks sur ma carte SD

Téléchargé http://www.startssl.com/certs/ca.crt et http://www.startssl.com/certs/sub.class1.server.ca.crt

Je suis allé sur portecle.sourceforge.net et j'ai exécuté portecle directement à partir de la page Web.

J'ai ouvert mon fichier cacerts.bks à partir de ma carte SD (rien entré lorsqu'on m'a demandé un mot de passe)

Choisissez l'importation dans portacle et ouvrez sub.class1.server.ca.crt, dans mon cas, il avait déjà le ca.crt mais peut-être que vous devez l'installer aussi.

Sauvegardé le keystore et copié baxck dans /system/etc/security/cacerts.bks (j'ai d'abord fait une sauvegarde de ce fichier au cas où)

J'ai redémarré mon téléphone et maintenant je peux visiter mon site qui utilise un certificat startssl sans erreurs.

Hans
la source
une idée comment remettre le cacert.bks sur un appareil NON rooté?
Bob
1

Ces étapes ont fonctionné pour moi:

  1. Installez l'application Android Dory Certificate sur votre appareil mobile: https://play.google.com/store/apps/details?id=io.tempage.dorycert&hl=en_US
  2. Connectez l'appareil mobile à l'ordinateur portable avec un câble USB.
  3. Créez un dossier racine sur la mémoire interne du téléphone, copiez le fichier de certificat dans ce dossier et déconnectez le câble.
  4. Ouvrez l'application Android Dory Certificate, cliquez sur le bouton rond [+] et sélectionnez la bonne option Importer le certificat de fichier.
  5. Sélectionnez le format, indiquez un nom (j'ai tapé le même nom que le nom du fichier), parcourez le fichier de certificat et cliquez sur [OK].
  6. Trois cartes s'afficheront. J'ai ignoré la carte qui n'avait que le bouton [SIGN CSR] et j'ai continué à cliquer sur le bouton [INSTALL] sur les deux autres cartes.
  7. J'ai actualisé l'application Web PWA que j'avais ouvert sur mon mobile Chrome (il est hébergé sur un serveur Web IIS local) et voala! Aucun message d'avertissement de chrome. Le verrou vert était là. Cela fonctionnait.

Alternativement, j'ai trouvé ces options que je n'avais pas besoin d'essayer moi-même mais qui semblaient faciles à suivre:

Enfin, cela peut ne pas être pertinent mais, si vous cherchez à créer et configurer un certificat auto-signé (avec mkcert) pour votre application PWA (site Web) hébergée sur un serveur Web IIS local, j'ai suivi cette page:

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

Merci et j'espère que cela vous aidera !! :)

Manuel Hernandez
la source
0

Voici une solution alternative qui ajoute réellement votre certificat à la liste intégrée des certificats par défaut: Faire confiance à tous les certificats à l'aide de HttpClient sur HTTPS

Cependant, cela ne fonctionnera que pour votre application. Il n'y a aucun moyen de le faire par programme pour toutes les applications sur l'appareil d'un utilisateur, car ce serait un risque pour la sécurité.

emmby
la source