Clés, informations d’identification et stockage sur Android

Dans l’article précédent sur la sécurité des données utilisateur Android, nous avons examiné le chiffrement des données via un code d’accès fourni par l’utilisateur. Ce didacticiel se concentrera sur le stockage des informations d’identification et des clés. Je vais commencer par présenter les informations d’identification du compte et terminer par un exemple de protection des données à l’aide du KeyStore.

Souvent, lorsque vous travaillez avec un service tiers, une forme d’authentification est requise. Cela peut être aussi simple qu’un /login point de terminaison qui accepte un nom d’utilisateur et un mot de passe.

Il semblerait au début qu’une solution simple consiste à créer une interface utilisateur qui demande à l’utilisateur de se connecter, puis à capturer et à stocker ses informations de connexion. Cependant, ce n’est pas la meilleure pratique, car notre application ne devrait pas avoir besoin de connaître les informations d’identification d’un compte tiers. Au lieu de cela, nous pouvons utiliser le gestionnaire de compte, qui délègue la gestion de ces informations sensibles pour nous.

Gestionnaire de compte

Le gestionnaire de compte est un assistant centralisé pour les informations d’identification du compte utilisateur afin que votre application n’ait pas à gérer directement les mots de passe. Il fournit souvent un jeton à la place du nom d’utilisateur et du mot de passe réels qui peuvent être utilisés pour faire des demandes authentifiées à un service. Un exemple est lors de la demande d’un Jeton OAuth2.

Parfois, toutes les informations requises sont déjà stockées sur l’appareil, et d’autres fois, le gestionnaire de compte devra appeler un serveur pour un jeton actualisé. Vous avez peut-être vu le Comptes section dans les paramètres de votre appareil pour diverses applications. Nous pouvons obtenir cette liste de comptes disponibles comme ceci:

Le code nécessitera le android.permission.GET_ACCOUNTS autorisation. Si vous recherchez un compte spécifique, vous pouvez le trouver comme ceci:

Une fois que vous avez le compte, un jeton pour le compte peut être récupéré en appelant le getAuthToken(Account, String, Bundle, Activity, AccountManagerCallback, Handler) méthode. Le jeton peut ensuite être utilisé pour envoyer des requêtes API authentifiées à un service. Il peut s’agir d’une API RESTful où vous transmettez un paramètre de jeton lors d’une requête HTTPS, sans jamais avoir à connaître les détails du compte privé de l’utilisateur.

Étant donné que chaque service aura une manière différente d’authentifier et de stocker les informations d’identification privées, le gestionnaire de compte fournit des modules d’authentification pour un service tiers à implémenter. Bien qu’Android ait des implémentations pour de nombreux services populaires, cela signifie que vous pouvez écrire votre propre authentificateur pour gérer l’authentification du compte et le stockage des informations d’identification de votre application. Cela vous permet de vous assurer que les informations d’identification sont cryptées. Gardez à l’esprit que cela signifie également que les informations d’identification dans le gestionnaire de compte qui sont utilisées par d’autres services peuvent être stockées en texte clair, ce qui les rend visibles à quiconque a rooté son appareil.

Au lieu de simples informations d’identification, vous devrez parfois gérer une clé ou un certificat pour une personne ou une entité, par exemple, lorsqu’un tiers vous envoie un fichier de certificat que vous devez conserver. Le scénario le plus courant est lorsqu’une application doit s’authentifier auprès du serveur d’une organisation privée.

Dans le prochain didacticiel, nous examinerons l’utilisation de certificats pour l’authentification et les communications sécurisées, mais je souhaite toujours expliquer comment stocker ces éléments entre-temps. L’API du trousseau a été conçue à l’origine pour cette utilisation très spécifique: installer une clé privée ou une paire de certificats à partir d’un fichier PKCS # 12.

Le trousseau

Introduite dans Android 4.0 (niveau d’API 14), l’API Keychain traite de la gestion des clés. Plus précisément, cela fonctionne avec PrivateKey et
X509Certificate objets et fournit un conteneur plus sécurisé que l’utilisation du stockage de données de votre application. En effet, les autorisations pour les clés privées permettent uniquement à votre propre application d’accéder aux clés, et uniquement après l’autorisation de l’utilisateur. Cela signifie qu’un écran de verrouillage doit être configuré sur l’appareil avant de pouvoir utiliser le stockage des informations d’identification. En outre, les objets du trousseau peuvent être liés à du matériel sécurisé, le cas échéant.

Le code pour installer un certificat est le suivant:

L’utilisateur sera invité à entrer un mot de passe pour accéder à la clé privée et une option pour nommer le certificat. Pour récupérer la clé, le code suivant présente une interface utilisateur qui permet à l’utilisateur de choisir dans la liste des clés installées.

Une fois le choix effectué, un nom d’alias de chaîne est renvoyé dans le alias(final String alias) callback où vous pouvez accéder directement à la clé privée ou à la chaîne de certificats.

Forts de ces connaissances, voyons maintenant comment nous pouvons utiliser le stockage des informations d’identification pour enregistrer vos propres données sensibles.

En relation :  4 façons de synchroniser et de télécharger des photos vers le stockage cloud sur Android

Le KeyStore

Dans le didacticiel précédent, nous avons examiné la protection des données via un code d’accès fourni par l’utilisateur. Ce type de configuration est bon, mais les exigences des applications évitent souvent que les utilisateurs se connectent à chaque fois et se souviennent d’un mot de passe supplémentaire.

C’est là que l’API KeyStore peut être utilisée. Depuis l’API 1, le KeyStore est utilisé par le système pour stocker les informations d’identification WiFi et VPN. À partir de 4.3 (API 18), il vous permet de travailler avec votre propre application asymétrique clés, et dans Android M (API 23), il peut stocker un AES
symétrique clé. Ainsi, bien que l’API ne permette pas de stocker directement des chaînes sensibles, ces clés peuvent être stockées puis utilisées pour crypter des chaînes.

L’avantage de stocker une clé dans le KeyStore est qu’il permet d’utiliser des clés sans exposer le contenu secret de cette clé; les données clés n’entrent pas dans l’espace de l’application. N’oubliez pas que les clés sont protégées par des autorisations afin que seule votre application puisse y accéder, et qu’elles peuvent en outre être sécurisées par le matériel si l’appareil en est capable. Cela crée un conteneur qui rend plus difficile l’extraction des clés d’un appareil.

Générer une nouvelle clé aléatoire

Pour cet exemple, au lieu de générer une clé AES à partir d’un mot de passe fourni par l’utilisateur, nous pouvons générer automatiquement une clé aléatoire qui sera protégée dans le KeyStore. Nous pouvons le faire en créant un KeyGenerator instance, définie sur "AndroidKeyStore" fournisseur.

Les éléments importants à examiner ici sont les .setUserAuthenticationRequired(true) et .setUserAuthenticationValidityDurationSeconds(120) Caractéristiques. Ceux-ci nécessitent la configuration d’un écran de verrouillage et le verrouillage de la clé jusqu’à ce que l’utilisateur se soit authentifié.

En regardant la documentation pour .setUserAuthenticationValidityDurationSeconds(), vous verrez que cela signifie que la clé n’est disponible qu’un certain nombre de secondes après l’authentification par mot de passe, et que le passage -1 nécessite une authentification par empreinte digitale chaque fois que vous souhaitez accéder à la clé. L’activation de l’exigence d’authentification a également pour effet de révoquer la clé lorsque l’utilisateur supprime ou modifie l’écran de verrouillage.

Parce que stocker une clé non protégée à côté des données cryptées revient à placer une clé domestique sous le paillasson, ces options tentent de protéger la clé au repos en cas de compromission d’un appareil. Un exemple pourrait être un vidage de données hors ligne de l’appareil. Sans que le mot de passe de l’appareil soit connu, ces données sont rendues inutiles.

le .setRandomizedEncryptionRequired(true) L’option active l’exigence qu’il y ait suffisamment de randomisation (une nouvelle IV aléatoire à chaque fois) pour que si les mêmes données sont cryptées une deuxième fois, cette sortie cryptée sera toujours différente. Cela empêche un attaquant d’obtenir des indices sur le texte chiffré en utilisant les mêmes données.

Une autre option à noter est setUserAuthenticationValidWhileOnBody(boolean remainsValid), qui verrouille la clé une fois que l’appareil a détecté qu’elle n’est plus sur la personne.

Chiffrement des données

Maintenant que la clé est stockée dans le KeyStore, nous pouvons créer une méthode qui crypte les données en utilisant le Cipher objet, étant donné le
SecretKey. Il renverra un HashMap contenant les données cryptées et un IV randomisé qui sera nécessaire pour décrypter les données. Les données cryptées, ainsi que l’IV, peuvent ensuite être enregistrées dans un fichier ou dans les préférences partagées.

Décryptage en un tableau d’octets

Pour le décryptage, l’inverse est appliqué. le Cipher l’objet est initialisé à l’aide de DECRYPT_MODE constante, et un décrypté byte[] tableau est renvoyé.

Tester l’exemple

Nous pouvons maintenant tester notre exemple!

En relation :  5 nouvelles applications Habit qui fonctionnent réellement pour atteindre vos objectifs

Utilisation des clés asymétriques RSA pour les appareils plus anciens

C’est une bonne solution pour stocker les données des versions M et supérieures, mais que faire si votre application prend en charge les versions antérieures? Alors que les clés symétriques AES ne sont pas prises en charge sous M, les clés asymétriques RSA le sont. Cela signifie que nous pouvons utiliser des clés RSA et un chiffrement pour accomplir la même chose.

La principale différence ici est qu’une paire de clés asymétrique contient deux clés, une clé privée et une clé publique, où la clé publique crypte les données et la clé privée les décrypte. UNE KeyPairGeneratorSpec est passé dans le KeyPairGenerator qui est initialisé avec KEY_ALGORITHM_RSA
et le "AndroidKeyStore" fournisseur.

Pour crypter, nous obtenons le RSAPublicKey de la paire de clés et utilisez-la avec le
Cipher objet.

Le déchiffrement se fait à l’aide du RSAPrivateKey objet.

Une chose à propos de RSA est que le cryptage est plus lent que dans AES. Cela convient généralement pour de petites quantités d’informations, par exemple lorsque vous sécurisez des chaînes de préférences partagées. Si vous constatez un problème de performances lors du chiffrement de grandes quantités de données, vous pouvez utiliser cet exemple à la place pour chiffrer et stocker uniquement une clé AES. Ensuite, utilisez le cryptage AES plus rapide qui a été abordé dans le didacticiel précédent pour le reste de vos données. Vous pouvez générer une nouvelle clé AES et la convertir en un
byte[] tableau compatible avec cet exemple.

Pour récupérer la clé des octets, procédez comme suit:

C’était beaucoup de code! Pour simplifier tous les exemples, j’ai omis la gestion approfondie des exceptions. Mais rappelez-vous que pour votre code de production, il n’est pas recommandé de tout simplement saisir Throwable cas dans une instruction catch.

Conclusion

Ceci termine le didacticiel sur l’utilisation des informations d’identification et des clés. Une grande partie de la confusion autour des clés et du stockage est liée à l’évolution du système d’exploitation Android, mais vous pouvez choisir la solution à utiliser en fonction du niveau d’API pris en charge par votre application.

Maintenant que nous avons couvert les meilleures pratiques pour sécuriser les données au repos, le prochain tutoriel se concentrera sur la sécurisation des données en transit.

Moyens Staff
Moyens I/O Staff vous a motivé, donner des conseils sur la technologie, le développement personnel, le style de vie et des stratégies qui vous aider.