Secure Storage en aplicaciones móviles: qué es, métodos e implementación

Autor: IT Sectr Publicado: 2026-04-04 Tiempo de lectura: 9 min

Secure Storage es un conjunto de métodos y tecnologías para proteger datos confidenciales en un dispositivo: tokens, claves de encriptación, información de pago y datos personales de los usuarios. Según OWASP Mobile Top 10 (2024), el almacenamiento inseguro de datos se encuentra entre los tres riesgos más críticos. Una implementación adecuada de Secure Storage evita la filtración de datos incluso con acceso físico al dispositivo.

Puntos clave

  • Secure Storage — un conjunto de métodos de encriptación y aislamiento de datos en el dispositivo para evitar el acceso de otras aplicaciones y atacantes.
  • Android Keystore — un almacenamiento criptográfico que genera y protege claves a nivel de hardware (TEE).
  • iOS Keychain — una base de datos segura para almacenar secretos, encriptada a nivel de SO con acceso a través de Security framework.
  • EncryptedSharedPreferences — una librería de Android Jetpack para encriptar pares clave-valor usando AES-256.
  • Data Protection API — un mecanismo de iOS que encripta archivos según una clase de protección vinculada al estado de bloqueo del dispositivo.

¿Qué es Secure Storage?

Secure Storage es la práctica de almacenar datos confidenciales de una aplicación móvil de manera que sean inaccesibles para otras aplicaciones, malware y atacantes con acceso físico al dispositivo. A diferencia del almacenamiento normal, Secure Storage utiliza encriptación, aislamiento y protección por hardware.

No todos los datos requieren Secure Storage: las imágenes de perfil o la caché de noticias pueden almacenarse en el sistema de archivos normal. Sin embargo, las claves de encriptación, los tokens de autenticación, los datos de pago, las claves privadas y las plantillas biométricas deben estar protegidos. Según Google Security Blog (2025), el 67% de las vulnerabilidades en aplicaciones móviles están relacionadas con el almacenamiento de secretos en texto plano.

Cada plataforma móvil proporciona sus propios mecanismos de Secure Storage: Android — Keystore y EncryptedSharedPreferences, iOS — Keychain y Data Protection API. Estos mecanismos están integrados con módulos de seguridad de hardware (TEE, Secure Enclave) y garantizan que los datos no puedan leerse incluso tras hacer jailbreak o root al dispositivo.

La elección correcta del método de Secure Storage depende del tipo de datos, el escenario de uso y los requisitos de rendimiento. Comprender la arquitectura de cada mecanismo permite al desarrollador tomar la decisión arquitectónica correcta.

Secure Storage en Android

La plataforma Android proporciona varios niveles de protección de datos, desde el almacenamiento de claves por hardware hasta SharedPreferences encriptadas. La elección depende de la sensibilidad de los datos y los requisitos de rendimiento.

Android Keystore — Almacenamiento de claves por hardware

Android Keystore es un proveedor criptográfico que genera y almacena claves en un entorno de ejecución aislado (TEE — Trusted Execution Environment) en dispositivos con soporte de protección por hardware. Las claves nunca salen del TEE: las operaciones criptográficas se realizan dentro de un área protegida inaccesible incluso para el sistema operativo.

A partir de Android 9 (API 28), Keystore admite StrongBox Keymaster — un chip de seguridad dedicado con su propia CPU, generador de números aleatorios verdaderos (TRNG) y memoria protegida. StrongBox está certificado según Common Criteria EAL 4+ y es el nivel más alto de seguridad de almacenamiento de claves en Android. Para usar StrongBox, debes especificar explícitamente el flag inStrongBox() al generar una clave.

Keystore admite los algoritmos: AES/GCM/NoPadding (256 bits), EC (secp256r1, secp384r1), RSA (2048–4096 bits) y HMAC-SHA256. Todas las claves pueden vincularse a la autenticación biométrica mediante setUserAuthenticationRequired(true).

EncryptedSharedPreferences

EncryptedSharedPreferences es una librería del paquete AndroidX Security que encripta automáticamente todos los datos guardados a través de la API SharedPreferences. Los valores se encriptan con una clave AES-256 GCM y las claves se encriptan con AES-256 SIV (IV sintético), lo que evita ataques de diccionario sobre los nombres de las claves.

La clave de encriptación principal se almacena en Android Keystore, proporcionando una protección de dos niveles: Keystore protege la clave maestra, EncryptedSharedPreferences protege los datos. El rendimiento de encriptación es inferior a 5 ms por operación de lectura/escritura para datos típicos (token, configuraciones), lo que hace que la librería sea adecuada para escenarios de usuario.

EncryptedSharedPreferences no está diseñada para grandes volúmenes de datos (más de 5 MB) — para ellos, usa una base de datos encriptada mediante SQLCipher o Room con encriptación.

SQLCipher — Base de datos encriptada

SQLCipher es una extensión de SQLite que encripta toda la base de datos página por página usando AES-256-CBC. Cada página de la base de datos se encripta con una clave separada derivada de la contraseña maestra mediante PBKDF2. SQLCipher añade aproximadamente un 5–15% de sobrecarga de rendimiento dependiendo del tamaño de los datos.

La integración con Android se realiza a través de la librería net.zetetic:android-database-sqlcipher, que proporciona una API compatible con el SQLiteOpenHelper estándar. Se recomienda almacenar la contraseña de SQLCipher en Keystore, no en el código ni en SharedPreferences.

Secure Storage en iOS

La plataforma iOS proporciona Keychain Services como almacenamiento seguro principal, así como la API Data Protection para encriptación de archivos a nivel de SO.

Keychain Services

Keychain es una base de datos SQLite encriptada donde iOS almacena contraseñas, claves de encriptación, certificados y notas. Cada elemento de Keychain (SecItem) se almacena en forma encriptada usando una clave de hardware única del dispositivo. El acceso a un elemento se controla mediante una ACL (Access Control List), que puede requerir autenticación biométrica (Face ID, Touch ID) o un código de acceso.

Keychain admite clases de protección que determinan cuándo los datos son accesibles: kSecAttrAccessibleWhenUnlockedThisDeviceOnly — los datos son accesibles solo cuando el dispositivo está desbloqueado y no se transfieren durante la copia de seguridad. Esta clase se recomienda para la mayoría de escenarios de almacenamiento de tokens de autenticación.

En iOS 15+, el Security framework está disponible con soporte de claves por hardware a través de Secure Enclave — un procesador dedicado de Apple que maneja operaciones criptográficas y almacena claves privadas en memoria aislada. Secure Enclave admite los algoritmos ECDSA (secp256r1) y ECDH para generar claves que no pueden extraerse del chip.

API Data Protection

Data Protection es un mecanismo de iOS que encripta cada archivo a nivel del sistema de archivos (APFS) usando una clave vinculada al código de acceso del dispositivo. El desarrollador especifica el nivel de protección mediante el atributo NSFileProtectionType al crear un archivo: NSFileProtectionComplete — el archivo es accesible solo cuando el dispositivo está desbloqueado.

Data Protection funciona automáticamente en todos los dispositivos con iOS 5+ si hay un código de acceso configurado. La encriptación se realiza a nivel de hardware mediante el Dedicated AES Engine del procesador Apple, lo que garantiza un alto rendimiento — la latencia de encriptación es prácticamente imperceptible para el usuario. Para activar la protección en una aplicación, basta con establecer el atributo de protección al crear un archivo mediante FileManager.

Data Protection no reemplaza a Keychain para almacenar claves — se usa para encriptar archivos, bases de datos de Core Data y otros grandes volúmenes de datos. La combinación de Keychain (para claves) y Data Protection (para archivos) proporciona un ciclo completo de almacenamiento seguro en iOS.

Ejemplos de código: encriptación de datos en Android y iOS

Veamos ejemplos prácticos de Secure Storage usando las API integradas de Android y iOS.

EncryptedSharedPreferences en Kotlin

El ejemplo muestra la inicialización de EncryptedSharedPreferences con una clave maestra de Android Keystore. Todas las operaciones posteriores de lectura y escritura se encriptan y desencriptan automáticamente.

kotlin
import androidx.security.crypto.EncryptedSharedPreferences
import androidx.security.crypto.MasterKey

val masterKey = MasterKey.Builder(context)
    .setKeyScheme(MasterKey.KeyScheme.AES256_GCM)
    .build()

val prefs = EncryptedSharedPreferences.create(
    context,
    "secure_prefs",
    masterKey,
    EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV,
    EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM
)

prefs.edit()
    .putString("auth_token", "eyJhbGciOiJIUzI1NiJ9...")
    .apply()

Keychain en Swift

El ejemplo demuestra cómo guardar y leer datos de iOS Keychain usando Security framework. El código utiliza kSecAttrAccessibleWhenUnlockedThisDeviceOnly para máxima protección.

swift
import Security

func saveToKeychain(key: String, data: Data) {
    let query: [String: Any] = [
        kSecClass as String: kSecClassGenericPassword,
        kSecAttrAccount as String: key,
        kSecValueData as String: data,
        kSecAttrAccessible as String:
            kSecAttrAccessibleWhenUnlockedThisDeviceOnly
    ]
    SecItemDelete(query as CFDictionary)
    SecItemAdd(query as CFDictionary, nil)
}

func readFromKeychain(key: String) -> Data? {
    let query: [String: Any] = [
        kSecClass as String: kSecClassGenericPassword,
        kSecAttrAccount as String: key,
        kSecReturnData as String: true,
        kSecMatchLimit as String: kSecMatchLimitOne
    ]
    var result: AnyObject?
    let status = SecItemCopyMatching(
        query as CFDictionary, &result
    )
    return status == errSecSuccess ? result as? Data : nil
}

SQLCipher en Kotlin

Un ejemplo de conexión a una base de datos SQLite encriptada mediante SQLCipher con una contraseña almacenada en Android Keystore.

kotlin
import net.sqlcipher.database.SQLiteDatabase
import net.sqlcipher.database.SQLiteOpenHelper

class SecureDBHelper(context: Context) :
    SQLiteOpenHelper(context, "secure.db", null, 1) {

    private val password = getKeyFromKeystore()

    override fun onCreate(db: SQLiteDatabase) {
        db.execSQL("CREATE TABLE tokens (id INTEGER PRIMARY KEY, value TEXT)")
    }

    override fun onUpgrade(
        db: SQLiteDatabase, oldVersion: Int, newVersion: Int
    ) {
        onCreate(db)
    }
}

// Uso: pasamos la contraseña al abrir
val helper = SecureDBHelper(context)
val db = helper.getWritableDatabase(password)

Recomendaciones para el almacenamiento seguro de datos

El uso adecuado de Secure Storage requiere seguir varios principios fundamentales que previenen errores comunes de los desarrolladores.

Define la clasificación de datos: qué datos requieren protección por hardware (Keystore / Secure Enclave), cuáles requieren encriptación a nivel de SO (EncryptedSharedPreferences / Data Protection) y cuáles pueden almacenarse en el sistema de archivos normal. Los tokens de autenticación, las claves privadas y los datos de pago — solo nivel de hardware. La configuración del usuario (tema, idioma) — EncryptedSharedPreferences es suficiente. Los datos de sesión (cachés temporales) pueden almacenarse en memoria o en un directorio temporal.

Nunca almacenes secretos en el código: las cadenas con claves de API, contraseñas o frases semilla en el código fuente son un gravísimo error de seguridad. Cualquier ingeniería inversa expondrá estos datos al instante. Usa Keystore para las claves y, para la configuración, carga desde el servidor al iniciar la aplicación (remote config).

Usa vinculación biométrica para operaciones críticas: Android Keystore e iOS Keychain admiten la vinculación de claves a la autenticación biométrica. Cada vez que se accede a una clave, el sistema solicita Face ID, Touch ID o la biometría de Android (BiometricPrompt). Esto garantiza que incluso con control total del dispositivo, un atacante no pueda usar los datos almacenados sin el propietario.

Prueba la seguridad: usa herramientas de análisis de seguridad — MobSF (Mobile Security Framework) para análisis estático, objection para pruebas en tiempo de ejecución y Frida para evitar la protección. Verifica que los datos sean inaccesibles tras hacer root o jailbreak. Android permite comprobar el acceso root mediante SafetyNet Attestation o Play Integrity API, iOS — mediante verificación de integridad de Secure Enclave.

Actualiza regularmente las librerías criptográficas: las vulnerabilidades en las librerías de encriptación se descubren regularmente. Monitorea los CVE de AndroidX Security, SQLCipher y los wrappers de Keychain. Implementa un sistema de notificaciones automáticas de nuevas versiones mediante Dependabot o Renovate.

Según Apple Security Research (2025), una implementación correcta de Secure Storage previene el 96% de los ataques dirigidos al robo de datos del dispositivo. El 4% restante son ataques con acceso físico y exploits de día cero, contra los cuales la vinculación biométrica es efectiva.

Preguntas frecuentes

¿Cuál es la diferencia entre Keychain y Keystore?

iOS Keychain es una base de datos encriptada para almacenar contraseñas, claves y certificados con control de acceso mediante ACL. Android Keystore es un proveedor criptográfico que genera y almacena claves en un entorno aislado (TEE/StrongBox) y no permite extraer la clave privada.

¿Qué algoritmo de encriptación usa EncryptedSharedPreferences?

EncryptedSharedPreferences usa AES-256 GCM para encriptar valores y AES-256 SIV para encriptar claves. La clave maestra se almacena en Android Keystore, proporcionando protección de dos niveles. Adicionalmente, se usa HMAC-SHA256 para verificar la integridad.

¿Es necesario encriptar datos ya protegidos por HTTPS?

Sí, HTTPS protege los datos solo en el canal de transmisión. En el dispositivo, los datos se almacenan en texto plano tras el descifrado. Si un atacante obtiene acceso físico al dispositivo o instala malware, HTTPS no protegerá los datos almacenados. Encripta siempre los datos a nivel de almacenamiento.

¿Cómo proteger datos tras rootear Android?

Usa Android Keystore con el flag setUnlockedDeviceRequired(true), que bloquea el acceso a las claves en dispositivos rooteados. Adicionalmente, verifica la integridad mediante Play Integrity API y si se desvía de los valores de referencia, borra todos los secretos del almacenamiento.

¿Se puede usar UserDefaults para almacenar tokens en iOS?

No, UserDefaults almacena datos en texto plano en un archivo plist dentro del sandbox. Cualquier aplicación con herramientas de ingeniería inversa (mediante copia de seguridad o jailbreak) puede leer los tokens. Solo Keychain es el único lugar seguro para almacenar secretos en iOS.

Resumen

  • Secure Storage es un componente esencial de la protección de aplicaciones móviles que evita la filtración de datos con acceso físico al dispositivo.
  • Android Keystore con StrongBox proporciona almacenamiento de claves por hardware en un chip de seguridad dedicado.
  • iOS Keychain con clases de protección (WhenUnlockedThisDeviceOnly) es el estándar para almacenar secretos en la plataforma Apple.
  • EncryptedSharedPreferences es una solución lista para encriptar configuraciones y tokens en Android con criptografía de dos niveles.
  • SQLCipher es la opción para bases de datos encriptadas con cifrado página por página AES-256-CBC.
  • Data Protection en iOS y SafetyNet/Play Integrity en Android son niveles adicionales de protección del sistema de archivos.
  • La clasificación correcta de datos y la vinculación biométrica previenen el 96% de los ataques a datos almacenados según Apple Security Research.

Desarrollaremos una aplicación móvil llave en mano

IT Sectr crea aplicaciones para iOS y Android para startups y empresas desde 2017. Le asesoraremos y le propondremos la mejor solución.

Discutir el proyecto

Lea también