En general, SharedPreferences es su mejor opción para almacenar preferencias, por lo que, en general, recomendaría ese enfoque para guardar la aplicación y la configuración del usuario.
La única área de preocupación aquí es lo que está ahorrando. Las contraseñas siempre son algo complicado de almacenar, y sería especialmente cuidadoso de almacenarlas como texto sin cifrar. La arquitectura de Android es tal que las Preferencias Compartidas de su aplicación están protegidas para evitar que otras aplicaciones puedan acceder a los valores, por lo que hay algo de seguridad allí, pero el acceso físico a un teléfono podría permitir el acceso a los valores.
Si es posible, consideraría modificar el servidor para usar un token negociado para proporcionar acceso, algo como OAuth . Alternativamente, es posible que necesite construir algún tipo de tienda criptográfica, aunque eso no es trivial. Como mínimo, asegúrese de cifrar la contraseña antes de escribirla en el disco.
MODE_PRIVATE
con SharedPreferences equivale a hacer lo mismo con un archivo creado en almacenamiento interno, en términos de efectividad para ofuscar los datos almacenados localmente?Estoy de acuerdo con Reto y fiXedd. Hablando objetivamente, no tiene mucho sentido invertir mucho tiempo y esfuerzo en encriptar las contraseñas en SharedPreferences, ya que es muy probable que cualquier atacante que tenga acceso a su archivo de preferencias también tenga acceso al binario de su aplicación y, por lo tanto, las claves para desencriptar el contraseña.
Sin embargo, dicho esto, parece haber una iniciativa publicitaria que continúa identificando aplicaciones móviles que almacenan sus contraseñas en texto sin cifrar en SharedPreferences y que arrojan luz desfavorable sobre esas aplicaciones. Consulte http://blogs.wsj.com/digits/2011/06/08/some-top-apps-put-data-at-risk/ y http://viaforensics.com/appwatchdog para ver algunos ejemplos.
Si bien necesitamos que se preste más atención a la seguridad en general, diría que este tipo de atención en este tema en particular no aumenta significativamente nuestra seguridad general. Sin embargo, como las percepciones son como son, aquí hay una solución para cifrar los datos que coloca en SharedPreferences.
Simplemente envuelva su propio objeto SharedPreferences en este, y cualquier dato que lea / escriba se cifrará y descifrará automáticamente. p.ej.
Aquí está el código para la clase:
fuente
La forma más sencilla de almacenar una preferencia única en una actividad de Android es hacer algo como esto:
Si le preocupa la seguridad de estos, siempre puede cifrar la contraseña antes de almacenarla.
fuente
Con el fragmento proporcionado por Richard, puede cifrar la contraseña antes de guardarla. Sin embargo, la API de preferencias no proporciona una manera fácil de interceptar el valor y cifrarlo: puede bloquearlo para que se guarde a través de un escucha OnPreferenceChange, y en teoría podría modificarlo a través de un preferenciasChangeListener, pero eso da como resultado un bucle sin fin.
Anteriormente había sugerido agregar una preferencia "oculta" para lograr esto. Definitivamente no es la mejor manera. Voy a presentar otras dos opciones que considero más viables.
Primero, el más simple, está en un PreferChangeListener, puede tomar el valor ingresado, cifrarlo y luego guardarlo en un archivo de preferencias alternativo:
La segunda forma, y la forma en que ahora prefiero, es crear su propia preferencia personalizada, extendiendo EditTextPreference, @ Override'ing
setText()
y losgetText()
métodos, de modo quesetText()
cifre la contraseña ygetText()
devuelva nulo.fuente
Bueno; Ha pasado un tiempo desde que la respuesta es un poco mixta, pero aquí hay algunas respuestas comunes. Investigué esto como loco y fue difícil construir una buena respuesta
El método MODE_PRIVATE se considera generalmente seguro, si supone que el usuario no ha rooteado el dispositivo. Sus datos se almacenan en texto plano en una parte del sistema de archivos a la que solo puede acceder el programa original. Esto hace que sea fácil obtener la contraseña con otra aplicación en un dispositivo rooteado. Por otra parte, ¿quieres soportar dispositivos rooteados?
AES sigue siendo el mejor cifrado que puede hacer. Recuerde buscar esto si está comenzando una nueva implementación si ha pasado un tiempo desde que publiqué esto. El mayor problema con esto es "¿Qué hacer con la clave de cifrado?"
Entonces, ahora estamos en "¿Qué hacer con la llave?" parte. Esta es la parte difícil. Obtener la llave no es tan malo. Puede usar una función de derivación de clave para tomar alguna contraseña y convertirla en una clave bastante segura. Tienes problemas como "¿cuántos pases haces con PKFDF2?", Pero ese es otro tema
Idealmente, almacena la clave AES fuera del dispositivo. Sin embargo, debe encontrar una buena manera de recuperar la clave del servidor de forma segura y confiable
Tiene una secuencia de inicio de sesión de algún tipo (incluso la secuencia de inicio de sesión original que tiene para el acceso remoto). Puede hacer dos ejecuciones de su generador de claves con la misma contraseña. Cómo funciona esto es que deriva la clave dos veces con una nueva sal y un nuevo vector de inicialización segura. Usted almacena una de esas contraseñas generadas en el dispositivo y usa la segunda contraseña como clave AES.
Cuando inicia sesión, deriva la clave en el inicio de sesión local y la compara con la clave almacenada. Una vez hecho esto, usa la clave de derivación # 2 para AES.
Puedes hacer muchas variaciones de estos. Por ejemplo, en lugar de una secuencia de inicio de sesión completa, puede hacer un PIN rápido (derivado). El PIN rápido puede no ser tan seguro como una secuencia de inicio de sesión completa, pero es muchas veces más seguro que el texto sin formato
fuente
Sé que esto es un poco de nigromancia, pero debes usar el Android AccountManager . Está especialmente diseñado para este escenario. Es un poco engorroso, pero una de las cosas que hace es invalidar las credenciales locales si la tarjeta SIM cambia, por lo que si alguien desliza su teléfono y arroja una nueva SIM, sus credenciales no se verán comprometidas.
Esto también le brinda al usuario una forma rápida y fácil de acceder (y potencialmente eliminar) las credenciales almacenadas para cualquier cuenta que tengan en el dispositivo, todo desde un solo lugar.
SampleSyncAdapter es un ejemplo que utiliza las credenciales de la cuenta almacenada.
fuente
Lanzaré mi sombrero al ring solo para hablar sobre la seguridad de las contraseñas en general en Android. En Android, el dispositivo binario debe considerarse comprometido; esto es lo mismo para cualquier aplicación final que esté bajo el control directo del usuario. Conceptualmente, un hacker podría usar el acceso necesario al binario para descompilarlo y eliminar sus contraseñas cifradas, etc.
Como tal, hay dos sugerencias que me gustaría lanzar si la seguridad es una preocupación importante para usted:
1) No almacene la contraseña real. Almacene un token de acceso otorgado y use el token de acceso y la firma del teléfono para autenticar la sesión del lado del servidor. El beneficio de esto es que puede hacer que el token tenga una duración limitada, no está comprometiendo la contraseña original y tiene una buena firma que puede usar para correlacionar el tráfico más tarde (por ejemplo, para verificar intentos de intrusión e invalidar el token que lo hace inútil).
2) Utilice la autenticación de 2 factores. Esto puede ser más molesto e intrusivo, pero para algunas situaciones de cumplimiento inevitable.
fuente
También puede consultar esta pequeña lib, que contiene la funcionalidad que menciona.
https://github.com/kovmarci86/android-secure-preferences
Es similar a algunos de los otros enfoques aquí. La esperanza ayuda :)
fuente
Esta es una respuesta complementaria para aquellos que llegan aquí según el título de la pregunta (como lo hice) y no necesitan lidiar con los problemas de seguridad relacionados con el almacenamiento de contraseñas.
Cómo usar las preferencias compartidas
La configuración del usuario generalmente se guarda localmente en Android usando
SharedPreferences
un par clave-valor. Usas elString
tecla para guardar o buscar el valor asociado.Escribir en preferencias compartidas
Usar en
apply()
lugar decommit()
guardar en segundo plano en lugar de inmediatamente.Leer desde preferencias compartidas
El valor predeterminado se usa si no se encuentra la clave.
Notas
En lugar de usar una cadena de clave local en varios lugares como lo hice anteriormente, sería mejor usar una constante en una sola ubicación. Podría usar algo como esto en la parte superior de su actividad de configuración:
He utilizado una
int
en mi ejemplo, pero también se puede utilizarputString()
,putBoolean()
,getString()
,getBoolean()
, etc.Consulte la documentación para más detalles.
Hay varias formas de obtener SharedPreferences. Vea esta respuesta para saber qué buscar.
fuente
Esta respuesta se basa en un enfoque sugerido por Mark. Se crea una versión personalizada de la clase EditTextPreference que convierte de ida y vuelta entre el texto sin formato que se ve en la vista y una versión cifrada de la contraseña almacenada en el almacenamiento de preferencias.
Como se ha señalado por la mayoría de los que respondieron en este hilo, esta no es una técnica muy segura, aunque el grado de seguridad depende en parte del código de cifrado / descifrado utilizado. Pero es bastante simple y conveniente, y frustrará la mayoría de los espías casuales.
Aquí está el código para la clase personalizada EditTextPreference:
Esto muestra cómo se puede usar: este es el archivo de "elementos" que controla la pantalla de preferencias. Tenga en cuenta que contiene tres vistas normales de EditTextPreference y una de las vistas personalizadas EditPasswordPreference.
En cuanto al cifrado / descifrado real, eso se deja como ejercicio para el lector. Actualmente estoy usando algún código basado en este artículo http://zenu.wordpress.com/2011/09/21/aes-128bit-cross-platform-java-and-c-encryption-compatibility/ , aunque con valores diferentes para la clave y el vector de inicialización.
fuente
En primer lugar, creo que los datos del usuario no deben almacenarse en el teléfono, y si es necesario almacenar datos en algún lugar del teléfono, deben cifrarse con los datos privados de las aplicaciones. La seguridad de las credenciales de los usuarios debe ser la prioridad de la aplicación.
Los datos confidenciales deben almacenarse de forma segura o no almacenarse. En caso de pérdida de dispositivo o infección de malware, los datos almacenados de forma insegura pueden verse comprometidos.
fuente
Uso Android KeyStore para cifrar la contraseña usando RSA en modo ECB y luego guardarla en SharedPreferences.
Cuando quiero recuperar la contraseña, leo la encriptada de SharedPreferences y la descifro usando KeyStore.
Con este método, genera un par de claves público / privado donde el privado se almacena y administra con seguridad en Android.
Aquí hay un enlace sobre cómo hacer esto: Tutorial de Android KeyStore
fuente
Las preferencias compartidas son la forma más fácil de almacenar los datos de nuestra aplicación. pero es posible que cualquiera pueda borrar nuestros datos de preferencias compartidas a través del administrador de aplicaciones. Por lo tanto, no creo que sea completamente seguro para nuestra aplicación.
fuente
necesita usar el sqlite, apit de seguridad para almacenar las contraseñas. este es el mejor ejemplo, que almacena contraseñas, - passwordsafe. Aquí hay un enlace para la fuente y la explicación: http://code.google.com/p/android-passwordsafe/
fuente