Unlimited Plugins, WordPress themes, videos & courses! Unlimited asset downloads! From $16.50/m
Advertisement
  1. Code
  2. Security
Code

Almacenar Datos de Forma Segura en Android

by
Difficulty:AdvancedLength:LongLanguages:

Spanish (Español) translation by Jean Perez (you can also view the original English article)

Credibilidad de la aplicación hoy en día altamente depende de cómo se maneja datos privados del usuario. La pila de Android tiene muchas potentes APIs circundante credencial y almacenamiento de claves, con específicas funciones sólo están disponibles en ciertas versiones. Esta serie corta comenzará con un enfoque simple para levantarse y correr mirando el sistema de almacenamiento y cómo cifrar y almacenar datos sensibles a través de un código de acceso suministrado por el usuario. En el segundo tutorial, veremos las formas más complejas de protección de claves y credenciales.

Los Conceptos Básicos

La primera pregunta que pensar es la cantidad de datos que realmente se necesita adquirir. Un buen enfoque es evitar almacenar datos privados si realmente no tienes que.

Para los datos que debe almacenar, la arquitectura Android está lista para ayudar. Desde 6.0 Marshmellow, cifrado de disco completo está activado por defecto, para los dispositivos con la capacidad. Archivos y SharedPreferences guardados por la aplicación se establecen automáticamente con la constante MODE_PRIVATE. Esto significa que los datos se pueden acceder sólo por su propia aplicación.

Es una buena idea atenerse a esta opción por defecto. Se puede establecer explícitamente al guardar una preferencia compartida.

O cuando se guarda un archivo.

Evitar el almacenamiento de datos en almacenamiento externo, como los datos están entonces visibles por otros usuarios y aplicaciones. De hecho, para evitar hacer lo más difícil para la gente a copiar el binario de la aplicación y datos, usted puede negar los usuarios de poder instalar la aplicación en almacenamiento externo. Añadir android:installLocation con un valor de internalOnly al archivo de manifiesto será lograrlo.

Puede también impedir la aplicación y sus datos están respaldados. Esto también evita que descarga el contenido del directorio de datos privados de una aplicación usando adb backup. Para ello, establezca el atributo android:allowBackup a false en el archivo de manifiesto. De forma predeterminada, este atributo se establece en true.

Estas son las mejores prácticas, pero no funcionará para un dispositivo comprometido o raíces, y el cifrado de disco sólo es útil cuando el dispositivo está asegurado con una pantalla de bloqueo. Aquí es donde tener una contraseña de aplicación lateral que protege sus datos con cifrado es beneficioso.

Protección de Datos de Usuario Con una Contraseña

Conceal es una gran opción para una biblioteca de cifrado porque le funcionar muy rápidamente sin tener que preocuparse de los detalles subyacentes. Sin embargo, una hazaña para un marco popular simultáneamente afectará a todos de las aplicaciones que confían en él.

También es importante estar bien informados acerca de cómo funcionan los sistemas de encriptación para poder si usted está usando un marco particular de bien. Por lo tanto, para este post vamos a ensuciar nuestras manos mirando directamente el proveedor de criptografía.

AES y Derivación de Claves Basada en Contraseña

Vamos a utilizar el estándar recomendado de AES, que cifra los datos dados una llave. Se utiliza la misma clave utilizada para cifrar los datos para desencriptar los datos, que se llaman cifrado simétrico. Hay diferentes tamaños de claves y AES256 (256 bits) es la longitud preferida para el uso con datos sensibles.

Mientras que la experiencia del usuario de la aplicación debe forzar a un usuario utilizar una contraseña fuerte, existe la posibilidad de que el mismo código de acceso también será elegido por otro usuario. No es seguro poner la seguridad de nuestros datos cifrados en manos del usuario. Nuestros datos deben fijarse en su lugar con una clave aleatoria y bastante grande (es decir. que tiene suficiente entropía) para considerarse fuerte. Por esta razón no se recomienda para usar una contraseña directamente para cifrar los datos, que es donde una función llamada función de derivación de clave contraseña-basado (PBKDF2) entra en juego.

PDKDF2 se deriva una clave de una contraseña por hashing muchas veces excedente con una sal. Esto se llama estiramiento clave. La sal es sólo una secuencia aleatoria de datos y la clave derivada única incluso si la contraseña fue utilizada por otra persona. Permite empezar por generar esa sal.

La clase SecureRandom garantiza que la salida generada será difícil de predecir, es un "criptográficamente fuerte generador de números aleatorios". Ahora podemos poner la sal y la contraseña en un objeto de cifrado basado en contraseña: PBEKeySpec. Constructor del objeto también toma una forma de la cuenta de iteración haciendo la clave más fuerte. Esto es porque aumenta el número de iteraciones expande el tiempo que tomaría para funcionar con un juego de llaves durante un ataque de fuerza bruta. El PBEKeySpec luego se pasa a la SecretKeyFactory, que finalmente genera la clave como un array de bytes []. Envolvemos matriz de crudo bytes [] en un objeto SecretKeySpec.

Tenga en cuenta que la contraseña se pasa como un array de char [] y la clase PBEKeySpec lo almacena como un char [] arreglo de discos así. arreglos de discos de Char [] se utilizan generalmente para funciones de cifrado porque mientras que la clase String es inmutable, se puede sobrescribir una matriz de char [] que contiene información confidencial, eliminando así los datos sensibles de República el dispositivo de la memoria RAM.

Vectores de Inicialización

Ahora estamos listos para cifrar los datos, pero tenemos una cosa más que hacer. Hay diferentes modos de encriptación con AES, pero usaremos una recomendada: bloque cifrado (CBC) de encadenamiento. Esto funciona en nuestros datos una cuadra a la vez. Lo bueno de este modo es que cada siguiente bloque cifrado de datos es XOR con el bloque cifrado anterior para hacer el cifrado más fuerte. Sin embargo, eso significa que el primer bloque no es tan único como todos los demás!

Si empiezan igual que otro mensaje a cifrar un mensaje a cifrar, la salida cifrada de principio sería el mismo, y que daría un atacante una pista para averiguar lo que podría ser el mensaje. La solución es utilizar un vector de inicialización (IV).

Un IV es sólo un bloque de bytes aleatorios que XOR con el primer bloque de datos de usuario. Puesto que cada bloque depende de todos los bloques de procesado hasta ese punto, todo el mensaje se cifrará únicamente — idénticos mensajes cifrados con la misma clave no producirá idénticos resultados. Permite crear un IV ahora.

Una nota sobre SecureRandom. En las versiones 4.3 y en la arquitectura de criptografía de Java tenía una vulnerabilidad debido a la inadecuada inicialización de la subyacente generador de números pseudoaleatorio (PRNG). Si usted está apuntando las versiones 4.3 y bajo, una solución está disponible.

Cifrar los Datos

Armado con un IvParameterSpec, ahora podemos hacer el cifrado real.

Aquí pasamos la cadena "AES/CBC/PKCS7Padding". Esto especifica cifrado AES con cypher block encadenamiento. La última parte de esta cadena se refiere a PKCS7, que es un estándar establecido para rellenar los datos que no encajan perfectamente en el tamaño de bloque. (Los bloques son de 128 bits y relleno se realiza antes del cifrado).

Para completar nuestro ejemplo, vamos a poner este código en un método de cifrado que empaquetará el resultado en un HashMap que contiene los datos cifrados, junto con la sal e inicialización vector necesario para el descifrado.

El Método de Descifrado

Sólo necesita almacenar la IV y la sal con sus datos. Mientras sales y IVs se consideran públicas, asegúrese de no secuencialmente se incrementa o reutilizados. Para descifrar los datos, todo lo que necesitamos hacer es cambiar el modo en el constructor de Cifra de ENCRYPT_MODE a DECRYPT_MODE. El método de descifrar tendrá un HashMap que contiene la misma información requerida (datos encriptados, sal y IV) y devolver una matriz de descifrados bytes [], dado la contraseña correcta. El método de descifrar regenerará la clave de cifrado de la contraseña. ¡Nunca debe almacenarse la clave!

Probar el Cifrado y Descifrado

Para mantener el ejemplo simple, estamos omitiendo de comprobación de errores que harían que el HashMap contiene la clave necesaria, pares de valores. Ahora podemos probar nuestros métodos para asegurar que los datos se desencripta correctamente después de cifrado.

Los métodos utilizan una matriz de byte [] que puede cifrar datos arbitrarios en vez de sólo objetos String.

Guardando Datos Cifrados

Ahora que tenemos una matriz de codificados bytes [], podemos guardarlo en almacenamiento de información.

Si no desea guardar el IV y sal por separado, HashMap es serializable con las clases ObjectInputStream y ObjectOutputStream.

Guardado seguros de datos a SharedPreferences

También puede guardar datos en SharedPreferences de su aplicación.

Puesto que el SharedPreferences es un sistema XML que acepte solamente tipos primitivos específicos y objetos como valores, necesitamos convertir nuestros datos en un formato compatible, como un objeto String. Base64 nos permite convertir los datos en bruto en una representación de cadena que contiene sólo los caracteres permitidos por el formato XML. Cifrar la clave y el valor para que un atacante no puede averiguar lo que un valor puede ser. En el ejemplo anterior, encryptedKey y encryptedValue son ambas matrices de cifrado byte [] devueltos por el método de encryptBytes(). La IV y la sal pueden guardarse en el archivo de preferencias o como un archivo independiente. Para obtener nuevamente los bytes cifrados desde el SharedPreferences, podemos aplicar un Base64 decodificar la cadena almacenada.

Limpiar Datos Inseguros de Versiones Antiguas

Ahora que los datos almacenados están seguros, puede ser el caso de que usted tiene una versión anterior de la aplicación que los datos almacenados de manera insegura. En una actualización, los datos podrían limpiar y volver a cifrado. El siguiente código borra sobre un archivo con datos aleatorios.

En teoría, sólo puede borrar sus preferencias compartidas eliminando los archivos /data/data/com.your.package.name/shared_prefs/your_prefs_name.xml y your_prefs_name.bak, y claro las preferencias en la memoria con el siguiente código:

Sin embargo, en lugar de intentar limpiar los datos antiguos y espero que funcione, es mejor cifrar en primer lugar! Esto es especialmente cierto en general para unidades de estado sólido que se extendían a menudo datos escribe a diferentes regiones para evitar el desgaste. Eso significa que incluso si se sobrescribe un archivo en el sistema de archivos, la memoria física de estado sólida podría conservar sus datos en su ubicación original en el disco.

Conclusión

Envuelve nuestro tutorial sobre almacenar datos cifrados. En este post, aprendió bien encriptar y desencriptar datos con una contraseña suministrados por el usuario. Es fácil de hacer cuando se sabe cómo, pero es importante seguir las mejores prácticas para asegurar los datos de sus usuarios están realmente seguros.

En el siguiente post, echamos un vistazo a cómo aprovechar el KeyStore y otro API relacionadas con credenciales para almacenar con seguridad artículos. Mientras tanto, revisa algunos de nuestros otros grandes artículos sobre desarrollo de aplicaciones Android.

Advertisement
Advertisement
Advertisement
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.