android - rct - Guarde los datos confidenciales en React Native
undefined is not an object react native video (4)
Estoy construyendo una aplicación React Native y necesito guardar algunos datos confidenciales como un token y un token de actualización. La solución obvia es guardar esa información usando AsyncStorage . El problema es el nivel de seguridad de AsyncStorage.
AsyncStorage proporciona una forma de almacenar localmente tokens y datos. Puede ser, de alguna manera, comparado con una opción LocalStorage. En aplicaciones de producción completa, se recomienda no acceder directamente a AsyncStorage, sino utilizar una capa de abstracción, ya que AsyncStorage se comparte con otras aplicaciones que utilizan el mismo navegador y, por lo tanto, una eliminación mal concebida de todos los elementos del almacenamiento podría perjudicar la funcionamiento de aplicaciones vecinas.
https://auth0.com/blog/adding-authentication-to-react-native-using-jwt/
En una aplicación nativa, elegiría Keychain
en iOS
y Shared Preferences
en modo privado en Android
.
Por lo que leí en la documentación provista por React Native:
En iOS, AsyncStorage está respaldado por código nativo que almacena valores pequeños en un diccionario serializado y valores más grandes en archivos separados. En Android, AsyncStorage usará RocksDB o SQLite en función de lo que esté disponible.
Nunca hablan sobre la seguridad de esos datos.
Es la mejor solución para crear un módulo para Android
(que usa Shared Preferences
en modo privado ) y otro para iOS
(que usa Keychain ) para guardar los datos sensibles. ¿O es seguro utilizar los métodos AsyncStorage
proporcionados?
Realmente te recomiendo usar una biblioteca como https://github.com/oblador/react-native-keychain para almacenar datos privados en react-native
Para el nivel de la API de Android:
- 16-22 usa Facebook Conceal
- 23+ usan Android Keystore
Puedes usarlo así:
// Generic Password, service argument optional
Keychain
.setGenericPassword(username, password)
.then(function() {
console.log(''Credentials saved successfully!'');
});
// service argument optional
Keychain
.getGenericPassword()
.then(function(credentials) {
console.log(''Credentials successfully loaded for user '' + credentials.username);
}).catch(function(error) {
console.log(''Keychain couldn/'t be accessed! Maybe no value set?'', error);
});
Si alguien quiere el paso adicional de cifrar los datos, es posible que desee ver esto: https://github.com/oblador/react-native-keychain
Utiliza Facebook ocultar internamente.
Solo profundizando en el código React Native, encontré la respuesta.
Androide
La implementación del módulo React Native
AsyncStorage
se basa en SQLiteOpenHelper
. El paquete donde se manejan todas las clases de datos: https://github.com/facebook/react-native/tree/master/ReactAndroid/src/main/java/com/facebook/react/modules/storage
La clase con las instrucciones para crear la base de datos: https://github.com/facebook/react-native/blob/master/ReactAndroid/src/main/java/com/facebook/react/modules/storage/ReactDatabaseSupplier.java
Según la documentación de Android, las bases de datos creadas por la aplicación se guardan en un espacio de disco privado asociado a la aplicación, por lo que es seguro.
Al igual que los archivos que guarda en el almacenamiento interno del dispositivo, Android almacena su base de datos en el espacio de disco privado de esa aplicación asociada. Sus datos son seguros porque, de forma predeterminada, otras aplicaciones no pueden acceder a este área.
iOS
En iOS, los valores de AsyncStorage
se guardan en archivos de diccionario serializados. Esos archivos se guardan en la aplicación NSDocumentDirectory
. En iOS, todas las aplicaciones viven en su propio entorno limitado , por lo que todos los archivos de una aplicación están protegidos, y las demás aplicaciones no pueden acceder a ellos.
El código en iOS que maneja el módulo AsyncStorage
se puede encontrar aquí: https://github.com/facebook/react-native/blob/master/React/Modules/RCTAsyncLocalStorage.m
Y como podemos ver here los archivos utilizados para almacenar los valores guardados por AsyncStorage
se guardan en NSDocumentDirectory
(dentro del entorno de sandbox de la aplicación).
Cada aplicación es una isla Las interacciones de una aplicación de iOS con el sistema de archivos están limitadas principalmente a los directorios dentro de la zona de pruebas de la aplicación. Durante la instalación de una nueva aplicación, el instalador crea una cantidad de contenedores para la aplicación. Cada contenedor tiene un rol específico. El contenedor del paquete contiene el paquete de la aplicación, mientras que el contenedor de datos contiene datos tanto para la aplicación como para el usuario. El contenedor de datos se divide además en una serie de directorios que la aplicación puede usar para ordenar y organizar sus datos. La aplicación también puede solicitar el acceso a contenedores adicionales, por ejemplo, el contenedor de iCloud, en tiempo de ejecución.
Conclusión
Es seguro utilizar AsyncStorage
para guardar tokens de usuario, ya que se guardan en un contexto seguro.
Tenga en cuenta que esto solo es cierto para dispositivos Android sin raíz y para dispositivos iOS sin jailbreak . Tenga en cuenta también que si el atacante tiene acceso físico al dispositivo y el dispositivo no está protegido. Puede conectar el dispositivo a la computadora portátil Mac y extraer el directorio de documentos y ver todos los contenidos guardados en el directorio de documentos.
AsyncStorage
guarda los pares clave-valor como un archivo JSON de texto plano en el directorio de Documentos. No cifra sus contenidos .
Este es un problema de seguridad (al menos en iOS) porque es posible que un atacante con acceso al dispositivo obtenga un volcado del contenido de la zona de pruebas y extraiga trivialmente cualquier información guardada a través de AsyncStorage
.
Esto solía no estar claramente indicado en los documentos para AsyncStorage.js, pero ahora es: https://github.com/facebook/react-native/pull/8809
También vea: https://.com/a/38398114/1072846