
Google I / O 2019 se ha apagado y es hora reescribir proyectos en una nueva arquitectura Aprende cosas nuevas. Como estoy interesado en la seguridad de las aplicaciones móviles, primero llamé la atención sobre la nueva biblioteca de la familia JetPack: security-crypto . La biblioteca ayuda a organizar el cifrado de datos correctamente y al mismo tiempo protege a los desarrolladores de todos los matices que acompañan este proceso.
Antecedentes historicos
El cifrado de datos en Android siempre ha generado mucha discusión. ¿Qué algoritmo elegir? ¿Qué modo de encriptación usar? ¿Qué es el relleno? ¿Dónde guardar las llaves? Aprender todo esto y mantener su conocimiento actualizado puede ser difícil para el desarrollador promedio. Por lo tanto, la historia a menudo terminaba en uno de tres escenarios:
- copiar y pegar la primera solución con stackoverflow
- buscar un "manual adecuado" con posterior implementación y recolección de rastrillos
- activación del protocolo "¡Y así será!"
A medida que la comunidad de desarrolladores de Android se desarrolló, las bibliotecas comenzaron a aparecer para ayudar a resolver este problema. La calidad de estas soluciones era muy diferente: de toda esta variedad, solo puedo seleccionar java-aes-crypto , que utilizamos en Redmadrobot. Una implementación de bastante alta calidad, pero hubo un par de problemas con ella.
En primer lugar, era solo el cifrado de cadenas. Esto en sí mismo no es malo, pero estas cadenas deben almacenarse en algún lugar, en la base de datos o SharedPreferences. Por lo tanto, debe escribir un contenedor sobre la fuente de datos para que todo esté encriptado sobre la marcha (lo que alguna vez hicimos). Pero este es el código que debe admitirse, arrastrarse de un proyecto a otro o ejecutarse en una biblioteca para facilitar su uso. Finalmente, esto también se hizo, pero no trajo consuelo a las mentes inquisitivas.
En segundo lugar, esta solución no ofrecía nada para resolver el problema de administración de claves. Podrían generarse, pero el almacenamiento cayó completamente sobre los hombros del desarrollador. Con todas las sentadillas alrededor de AndroidKeystore en diferentes versiones del sistema operativo y dispositivos procedentes de China continental.
Esta ciudad necesita un nuevo héroe.
Todo salió como de costumbre hasta que en el verano de 2018, descubrí que hay una biblioteca tan maravillosa de Google como Tink . Es bastante fácil de aprender y protege al desarrollador de una gran cantidad de matices relacionados con la criptografía. Con esta biblioteca, es casi imposible hacer algo mal. Además, Tink toma el control total de las claves y abstrae todas las operaciones con AndroidKeystore del desarrollador.
Pero todavía era solo el cifrado de cadenas. Y aquí las Preferencias binarias aparecieron con mucho éxito: una biblioteca de un fabricante nacional que había querido ver durante mucho tiempo. Le permite cifrar todos los datos almacenados de cualquier algoritmo; para esto fue suficiente escribir una implementación de dos interfaces, KeyEncryption y ValueEncryption (para claves y valores, respectivamente).
Como resultado, comenzamos a usar estas dos bibliotecas en conjunto y nos alegramos de que nuestro código se volviera más limpio y fácil de entender.
seguridad-cripto

Ahora Google ha decidido una vez más reunirse con los desarrolladores y simplificar sus vidas en el campo del cifrado de datos almacenados. Se anunció otra biblioteca JetPack para ayudar con esto. Me preguntaba qué escribieron allí tan revolucionario, y subí a buscar documentación (spoiler: no lo es). Solo encontré javadoc en las clases incluidas en la biblioteca, pero gracias por eso también. Resultó que hay pocas oportunidades: cifrado de archivos, SharedPreferences y trabajar con claves.
Para probar la funcionalidad de la biblioteca, escribí un par de fragmentos:
Cifrado de archivosval 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()) }
Cifrado de preferencias compartidas 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")
Para mi gran sorpresa, todo funcionó la primera vez, y pude ver qué código escribieron para esta biblioteca. Habiendo caído en la fuente, vi que esto es en realidad una envoltura alrededor de la biblioteca Tink que ya conocemos, y el código escrito es casi uno a uno como escribimos para las Preferencias Binarias cifradas.
Estaba muy contento de que esta vez Google no inventó un ciclomotor para bicicletas, sino que utilizó sus propias prácticas bien establecidas. Esperemos que el paquete de security
que llegó a JetPack no se limite solo a esta biblioteca, sino que se desarrolle aún más.
Demostración de las preferencias binarias + Tink Bundle
Código fuente de la biblioteca de cifrado de seguridad
Seguridad-cripto demo