
Google I / O 2019 est mort et il est temps réécrire des projets sur une nouvelle architecture apprendre de nouvelles choses. Comme je suis intéressé par la sécurité des applications mobiles, j'ai d'abord attiré l'attention sur la nouvelle bibliothèque de la famille JetPack - security-crypto . La bibliothèque aide à organiser correctement le chiffrement des données et protège en même temps les développeurs de toutes les nuances qui accompagnent ce processus.
Contexte historique
Le cryptage des données dans Android a toujours suscité beaucoup de discussions. Quel algorithme choisir? Quel mode de cryptage utiliser? Qu'est-ce que le rembourrage? Où stocker les clés? Apprendre tout cela et maintenir vos connaissances à jour peut être difficile pour le développeur moyen. Par conséquent, l'histoire se terminait le plus souvent dans l'un des trois scénarios suivants:
- copier-coller de la première solution avec stackoverflow
- recherche d'un «manuel approprié» avec mise en œuvre et collecte ultérieures de râteaux
- activation du protocole «Et il en sera ainsi!»
À mesure que la communauté des développeurs Android se développait, des bibliothèques ont commencé à apparaître pour aider à résoudre ce problème. La qualité de ces solutions était très différente: parmi toute cette variété, je ne peux sélectionner que java-aes-crypto , que nous avons utilisé dans Redmadrobot. Une implémentation plutôt de haute qualité, mais avec quelques problèmes.
Tout d'abord, c'était juste un cryptage de chaîne. Ce n'est pas mauvais en soi, mais ces chaînes doivent être stockées quelque part, dans la base de données ou SharedPreferences. Donc, vous devez écrire un wrapper sur la source de données afin que tout soit chiffré à la volée (ce que nous avons fait une fois). Mais c'est le code qui doit être pris en charge, glissé de projet en projet ou exécuté dans une bibliothèque pour une facilité d'utilisation. En fin de compte, cela a également été fait, mais cela n'a pas rassuré les esprits curieux.
Deuxièmement, cette solution n'a rien offert pour résoudre le problème de gestion des clés. Ils pouvaient être générés, mais le stockage tombait complètement sur les épaules du développeur. Avec tous les squats autour d'AndroidKeystore sur différentes versions de systèmes d'exploitation et appareils provenant de Chine continentale.
Cette ville a besoin d'un nouveau héros
Tout s'est déroulé comme d'habitude jusqu'à l'été 2018, j'ai découvert qu'il existe une merveilleuse bibliothèque de Google comme Tink . Il est assez facile à apprendre et protège le développeur d'un grand nombre de nuances liées à la cryptographie. En utilisant cette bibliothèque, il est presque impossible de faire quelque chose de mal. De plus, Tink prend le contrôle total des clés et résume toutes les opérations avec AndroidKeystore du développeur.
Mais ce n'était encore que le cryptage des chaînes. Et ici, les préférences binaires sont apparues avec beaucoup de succès - une bibliothèque d'un fabricant national que j'ai longtemps voulu regarder. Il vous permet de crypter toutes les données stockées de tous les algorithmes - pour cela, il suffisait d'écrire une implémentation de deux interfaces, KeyEncryption et ValueEncryption (pour les clés et les valeurs, respectivement).
En conséquence, nous avons commencé à utiliser ces deux bibliothèques conjointement et étions heureux que notre code soit devenu plus propre et plus facile à comprendre.
sécurité-crypto

Maintenant, Google a de nouveau décidé de rencontrer les développeurs et de simplifier leur vie dans le domaine du cryptage des données stockées. Une autre bibliothèque JetPack a été annoncée pour aider à cela. Je me demandais ce qu'ils ont écrit de si révolutionnaire là-bas, et j'ai grimpé à la recherche de documentation (spoiler: ce n'est pas le cas). Je n'ai trouvé que javadoc sur les classes incluses dans la bibliothèque, mais merci aussi. Il s'est avéré qu'il y a peu d'opportunités: cryptage de fichiers, SharedPreferences et travailler avec des clés.
Pour tester la fonctionnalité de la bibliothèque, j'ai écrit quelques extraits:
Cryptage de fichiersval file = File(filesDir, "super_secure_file") val encryptedFile = EncryptedFile.Builder(file, this, "my_secret_key", EncryptedFile.FileEncryptionScheme.AES256_GCM_HKDF_4KB) .setKeysetAlias("my_test_keyset_alias") .setKeysetPrefName("keyset_pref_file") .build() val outputStream = encryptedFile.openFileOutput() outputStream.use { it.write("secret info".toByteArray()) }
Cryptage SharedPreferences val encryptedPreferences = EncryptedSharedPreferences.create( "super_secret_preferences", "prefrences_master_key", this, EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV, EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM ) encryptedPreferences.edit().putString("secret", "super secret token")
À ma grande surprise, tout a fonctionné la première fois, et j'ai pu voir quel code ils ont écrit pour cette bibliothèque. Après être tombé dans la source, j'ai vu qu'il s'agit en fait d'un wrapper autour de la bibliothèque Tink que nous connaissons déjà, et le code écrit est presque un à un comme nous l'avons écrit pour les BinaryPreferences chiffrées.
J'étais très heureux que Google, cette fois, n'ait pas commencé à inventer un cyclomoteur, mais ait utilisé ses propres pratiques bien établies. Espérons que le package de security
fourni avec JetPack ne sera pas limité à cette bibliothèque uniquement, mais se développera davantage.
Démonstration du pack BinaryPreferences + Tink
Code source de la bibliothèque de chiffrement de sécurité
Démo de sécurité-crypto