Como Encriptar los Datos Almacenados en Shared Preferences de Android
En esta página:
Demo Github
Una aplicación Android puede guardar datos importantes internamente en el equipo o dispositivo móvil, exactamente en Shared Preferences pero no es útil para guardar datos grandes, para datos grandes se puede usar SQLite, Firebase, consumir los datos mediante API REST, etc. Los datos que se almacenan en Shared Preferences son muy fáciles de leer y un usuario con los conocimientos necesarios puede hacerlo, pero Android lanzo un funcionalidad que nos permite encriptar los datos que se almacenan en Shared Preferences y en este Post veremos como funciona.
Antes del SDK 23 de Android (Android 6.0), se utilizaban herramientas extras para poder encriptar la información en Shared Preferences y en muchos casos los Desarrolladores evitaban hacer esta tarea de encriptación.
A partir del SDK 23 y en adelante, podemos hacer uso del método o clase EncryptedSharedPreferences que nos permite encriptar fácilmente los datos sin necesidad de usar una herramienta extra, es decir, de manera nativa en Android.
Guardando Datos en Shared Preferences
Bien voy a guardar unos 3 datos en Shared Preferences, específicamente son datos de un postre o producto:
1 2 3 4 5 |
Nombre: Gelatina de Fresa Stock: 35 Precio: 2.50 |
En mi archivo MainActivity.java dentro del método onCreate guardo los datos en Shared Preferences de manera normal
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
package com.example.holamundojava; import androidx.appcompat.app.AppCompatActivity; import android.content.Context; import android.os.Bundle; import android.content.Intent; import android.widget.EditText; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.content.SharedPreferences; public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); SharedPreferences pref = getApplicationContext().getSharedPreferences("Datos", MODE_PRIVATE); SharedPreferences.Editor editor = pref.edit(); // Datos a guardar en Shared Preferences editor.putString("Nombre", "Gelatina de Fresa"); editor.putString("Precio", "2.50"); editor.putString("Stock", "35"); editor.apply(); } } |
Corro mi aplicación en el dispositivo móvil o emulador y se debió de guardar los datos internamente en Shared Preferences, para verificar si los datos se han almacenado correctamente voy a Device File Explorer > data > data > com.miapp.miapp > shared_prefs > Datos.xml
Si deseas puedes ver el siguiente video, en donde explico a detalle como ver los datos almacenados en Shared Preferences:
El archivo que he creado es Datos.xml y si lo abro, en su interior se encuentra los datos guardados correctamente:
1 2 3 4 5 6 7 8 |
<?xml version='1.0' encoding='utf-8' standalone='yes' ?> <map> <string name="Nombre">Gelatina de Fresa</string> <string name="Stock">35</string> <string name="Precio">2.50</string> </map> |
Con esto he guardado los Datos sin problemas, pero supongamos que estos datos son datos muy importantes y queremos que estos datos se encripten, a continuación veremos como hacerlo.
Encriptar los Datos Almacenados en Shared Preferences
Para comenzar a usar la encriptación de los datos almacenados en Shared Preferences, primero debemos añadir la dependencia correspondiente, para esto abre el archivo build.gradle (Module: app) que se encuentra en Gradle Scripts > build.gradle (Module: app)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
/app ├── /manifests ├── /java ├── /java (generated) ├── /res ├── /res (generated) /Gradle Scripts ├── build.gradle (Project: HolaMundoJava) ├── build.gradle (Module: app) // Abre este Archivo ├── gradle-wrapper.properties (Gradle Version) ├── proguard-rules.pro (ProGuard Rules for app) ├── gradle.properties (Project Properties) ├── settings.gradle (Project Settings) ├── local.properties (SDK Location) |
En el archivo build.gradle (Module: app) dentro de la linea dependencies (dependencias) añade la dependencia de seguridad de Android:
1 2 3 4 5 6 7 8 9 10 11 12 |
dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) implementation 'androidx.appcompat:appcompat:1.1.0' implementation 'androidx.constraintlayout:constraintlayout:1.1.3' implementation "androidx.security:security-crypto:1.0.0-alpha02" // Agrega esta dependencia de seguridad de Android testImplementation 'junit:junit:4.12' androidTestImplementation 'androidx.test.ext:junit:1.1.1' androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' } |
Bien ahora voy a modificar en el código la forma de guardar los Datos en Shared Preferences, de esta manera voy a encriptar los datos:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
package com.example.holamundojava; import androidx.appcompat.app.AppCompatActivity; import androidx.security.crypto.EncryptedSharedPreferences; import androidx.security.crypto.MasterKeys; import android.os.Bundle; import android.content.SharedPreferences; import java.io.IOException; import java.security.GeneralSecurityException; public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); String encriptar = null; try { encriptar = MasterKeys.getOrCreate(MasterKeys.AES256_GCM_SPEC); } catch (GeneralSecurityException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } SharedPreferences sharedPreferences = null; try { sharedPreferences = EncryptedSharedPreferences.create( "Datos Encriptados", encriptar, this, EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV, EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM ); } catch (GeneralSecurityException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } // Guardo los datos encriptandolos en Shared Preferences sharedPreferences.edit() .putString("Nombre", "Gelatina de Fresa") .putString("Precio", "2.50") .putString("Stock", "35") .apply(); } } |
Lo que hice es usar el método MasterKeys de Android para crear varios Strings encriptado con el formato AES256_GCM_SPEC, luego lo coloco dentro la variable sharedPreferences y mas abajo paso esta variable a la hora de crear los datos en Shared Preferences.
Bien ahora, para verificar si los datos se han encriptado y almacenado correctamente voy a Device File Explorer > data > data > com.miapp.miapp > shared_prefs > Datos Encriptados.xml y puedo ver que los datos ahora están Encriptados:
1 2 3 4 5 6 7 8 9 10 |
<?xml version='1.0' encoding='utf-8' standalone='yes' ?> <map> <string name="__androidx_security_crypto_encrypted_prefs_key_keyset__">12a901edb3711aa7760d3e6e492090a983296ac3754862565c17ce5bccb34a3fe1f6cde1cb844fbbe53593356fd2f8460464069141950e9128164f0e88979ad1250c147fccb0a44759c9ea071a3b2905825696d36698a38237fc9e7282891450ada277ee3b7db966c6ff08f54078b1e3f73d590651a09aa1daec74c87a2b1247c589e84d8cc3d7509ee8dff4d77f7687e8a7ce194b9a2cee5a1178c3908fd649de6643adab3da2211f71c83b1a4408c2c1ecd706123c0a30747970652e676f6f676c65617069732e636f6d2f676f6f676c652e63727970746f2e74696e6b2e4165735369764b6579100118c2c1ecd7062001</string> <string name="AWr7IMJ0yOod4FoJUwRVwQ7zZKjxKvFrFEI=">AUh9SofvA5UuwjlsnG5KJLQHp9NEFkiNj70X1kvPMQ7Wsw58JWrK17PhLQ==</string> <string name="__androidx_security_crypto_encrypted_prefs_value_keyset__">1288015d0471f6f647cfcf20e8d7836cb2d635765b285eae4e0069e7e2261dbd43b4f96e2d42e88580682e986aaa409b5c2fee74b9f6bb31725d367b7e2d0050696670000ccab0d1f3494cdef9789304371ed4859084ffbc2fd2ad25f78347d55c630d96862e3a87ab3cce1b04a13e9e569c12d593b87dec8899bd95aeea3da75ee50bf5b22054846d99011a44088795f5c304123c0a30747970652e676f6f676c65617069732e636f6d2f676f6f676c652e63727970746f2e74696e6b2e41657347636d4b65791001188795f5c3042001</string> <string name="AWr7IMKGxKdUxW/f9RatEKAbdGKCZajoizmS">AUh9SodBbrGUXRFsIE9XYyEaklnC2kVeGWl358pQc8vixGCBYvqg8SvqefLC</string> <string name="AWr7IMJSFX11J7z0vVKq46olHIYG4aC/7ZtB">AUh9SodNoQj0urGsrSVBDrBVHISyCkGGysrCRFu+ZlH/dFAVSx2KjDCpsA7sHcJgf1MacRUWB0sFPg==</string> </map> |
Con esta encriptación ahora los datos cuentan con una capa de seguridad extra, los datos encriptados cambian constantemente, cada ves que la aplicación se lance nuevamente.
Leer los Datos Encriptados en Shared Preferences
En el Demo de este Post, no explico como leer los datos encriptados en Shared Preferences, pero para hacerlo solo necesitas hacer lo siguiente, por ejemplo si quiero llamar el dato Nombre:
1 2 3 4 5 6 7 8 |
// Leer los datos Encriptados en Shared Preferences String nombre = sharedPreferences.getString("Nombre", ""); Log.e("Nombre", nombre); // Obtengo el nombre del postre o producto Nombre: Gelatina de Fresa |
De esta manera podemos leer dato por dato o los datos que desees de Shared Preferences.
Conclusión
En este Post hemos visto que encriptar los Datos es algo muy fácil, yo hice prueba con datos de un producto o postre, pero si tu tienes datos muy confidenciales, es importante que los encriptes, por seguridad.
Al inicio del Post, hay un Demo en donde puedes ver la encriptación en acción.
Nota(s)
- Algunos de los métodos y pasos mencionados en este Post, puede ser modificados, continuar o ser eliminados, esto no depende de mi si no de los Desarrolladores que dan soporte a Android Studio.
- No olvides que debemos usar la Tecnología para hacer cosas Buenas por el Mundo.
Síguenos en nuestras Redes Sociales para que no te pierdas nuestros próximos contenido.
- Android Tutoriales
- 19-02-2020
- 20-02-2020
- Crear un Post - Eventos Devs - Foro
Social
Redes Sociales (Developers)
Redes Sociales (Digital)