EncryptedSharedPreferences: qué es, API y cómo usarlo

Autor: IT Sectr Publicado: 2026-03-14 Tiempo de lectura: 10 min

EncryptedSharedPreferences es un componente de la biblioteca AndroidX Security que proporciona cifrado transparente de los datos guardados a través de la API SharedPreferences. A diferencia de las SharedPreferences normales, donde los datos se almacenan en un archivo XML sin cifrar, EncryptedSharedPreferences cifra automáticamente las claves y los valores antes de escribirlos en el disco. Según Android Developers, la biblioteca utiliza AES-256 GCM para los valores y AES-256 SIV (RFC 5297) para las claves, garantizando la confidencialidad e integridad de los datos.

Puntos Clave

  • EncryptedSharedPreferences — un envoltorio sobre SharedPreferences con cifrado automático de todos los datos guardados
  • El cifrado utiliza AES-256 GCM para los valores y AES-256 SIV para las claves a través de Android Keystore
  • Authenticated Encryption (AEAD) garantiza que los datos no hayan sido alterados después de la escritura
  • Master Key se almacena en Android Keystore y está protegida por hardware en dispositivos con TEE
  • La API es totalmente compatible con SharedPreferences — el reemplazo se produce sin cambiar el código de lectura y escritura

¿Qué es EncryptedSharedPreferences?

EncryptedSharedPreferences es una clase del paquete androidx.security.crypto, presentada en AndroidX Security 1.0.0 (2019). Implementa la interfaz SharedPreferences, pero todas las operaciones de escritura (putString, putInt, putBoolean, etc.) cifran los datos de antemano, y las operaciones de lectura los descifran antes de devolverlos.

El problema de las SharedPreferences normales

Las SharedPreferences estándar guardan los datos en un archivo XML en el directorio de la aplicación (/data/data/package/shared_prefs/). El archivo no está cifrado — con acceso root al dispositivo o durante el análisis de la copia de seguridad, todos los datos se leen como XML sin formato. Los tokens de autenticación, las claves API y los datos personales del usuario quedan accesibles para un atacante.

EncryptedSharedPreferences resuelve este problema a nivel de biblioteca: los datos se cifran antes de escribirlos en el disco y se descifran al leerlos. El desarrollador no necesita llamar a funciones criptográficas manualmente — la API sigue siendo idéntica a las SharedPreferences normales.

Historia y versiones

La biblioteca AndroidX Security v1.0.0 se lanzó en diciembre de 2019. EncryptedSharedPreferences reemplazó el enfoque obsoleto de cifrado manual mediante Cipher + SharedPreferences. La versión estable actual es 1.1.0-alpha06 (2024), compatible con API 19+. La biblioteca forma parte de Jetpack y no requiere permisos adicionales.

Según Google Security Blog (2024), EncryptedSharedPreferences es la forma recomendada de almacenar configuraciones confidenciales de la aplicación que no requieren sincronización en la nube. Para escenarios más complejos, se recomienda Room con cifrado SQLCipher.

¿Cómo funciona EncryptedSharedPreferences?

EncryptedSharedPreferences utiliza un esquema de cifrado de dos niveles: la Master Key se almacena en Android Keystore y se utilizan claves derivadas para el cifrado de datos. Esto combina la protección de Keystore con el rendimiento del cifrado simétrico.

Esquema de cifrado: AES-256 GCM + SIV

Para los valores se utiliza AES-256 GCM (modo Galois/Counter) — un modo de cifrado autenticado (AEAD) que garantiza la confidencialidad e integridad de los datos. Para las claves (nombres de parámetros) se aplica AES-256 SIV (RFC 5297) — cifrado determinista necesario para la búsqueda de claves sin revelar su contenido.

Cada archivo de EncryptedSharedPreferences contiene pares clave-valor cifrados. La estructura del archivo incluye: primero un encabezado con metadatos (versión, identificador de clave), luego una lista de entradas cifradas. El archivo no es XML válido y no se puede leer con editores de texto.

MasterKey y KeyStore

La clase MasterKey se encarga de crear y gestionar una clave maestra de 256 bits almacenada en Android Keystore. MasterKey.Builder permite configurar: el tipo de almacenamiento (Keystore o software), la protección biométrica y la vida útil de la clave. Por defecto, la clave maestra se genera en Android Keystore con el algoritmo AES/GCM/NoPadding.

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

fun getEncryptedPrefs() {
    val masterKey = MasterKey.Builder(context)
        .setKeyScheme(MasterKey.AES256_GCM_SPEC)
        .build()

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

Configuración del cifrado

EncryptedSharedPreferences.create acepta cinco parámetros: contexto, nombre de archivo, clave maestra, esquema de cifrado de claves y esquema de cifrado de valores. La elección de los esquemas afecta al rendimiento y al nivel de seguridad.

Esquemas de cifrado de claves

AES256_SIV — cifrado determinista: claves idénticas siempre producen el mismo texto cifrado. Esto es necesario para la búsqueda de claves (SharedPreferences.getX(key)). Inconveniente: un atacante puede determinar qué claves se utilizan comparando textos cifrados repetidos. AES256_SIV2 — una versión mejorada con aleatorización adicional.

Para los valores se utiliza AES256_GCM. GCM añade un IV de 12 bytes (vector de inicialización) y una etiqueta de autenticación de 16 bytes a cada valor. Esto proporciona confidencialidad (nadie puede leer el valor) y autenticación (nadie puede manipular el valor sin ser detectado).

Protección biométrica de la clave maestra

El método setUserAuthenticationRequired(true) en MasterKey.Builder requiere confirmación biométrica antes de recuperar la clave maestra de Keystore. Esto añade una capa adicional: incluso si la aplicación se ejecuta en un dispositivo desbloqueado, un atacante no puede leer EncryptedSharedPreferences sin Face ID o Touch ID.

Importante: con setUserAuthenticationRequired, la clave maestra deja de estar disponible si el usuario cambia o elimina los datos biométricos. Debe manejar KeyPermanentlyInvalidatedException y crear una nueva clave maestra con migración de datos.

kotlin
fun createBiometricKey(): MasterKey {
    return MasterKey.Builder(context)
        .setKeyScheme(MasterKey.AES256_GCM_SPEC)
        .setUserAuthenticationRequired(true)
        .setRequestStrongBoxBacked(true)
        .build()
}

fun writeSecureToken(token: String) {
    try {
        prefs.edit().putString("auth_token", token).apply()
    } catch (e: KeyPermanentlyInvalidatedException) {
        // La biometría ha cambiado — es necesario recrear la clave
    }
}

Ejemplo de uso en Kotlin

Veamos un ejemplo completo de integración de EncryptedSharedPreferences en una aplicación Android con Kotlin. La biblioteca androidx.security:security-crypto se añade a través de Gradle.

Añadir la dependencia

En el archivo build.gradle (app), añada: implementation "androidx.security:security-crypto:1.1.0-alpha06". Para proyectos Kotlin, también se requiere kotlin-stdlib. La inicialización de MasterKey ocurre una vez, normalmente en Application.onCreate o a través de un contenedor DI.

Lectura y escritura de datos

Después de crear una instancia de EncryptedSharedPreferences, la API no difiere de las SharedPreferences normales. edit() devuelve un Editor, todos los métodos (putString, getString, putBoolean, getBoolean) funcionan de la misma manera. La única diferencia es interna: los datos se cifran al escribir y se descifran al leer.

kotlin
class AuthRepository(context: Context) {
    private val prefs = createEncryptedPrefs(context)

    fun saveCredentials(login: String, password: String) {
        prefs.edit()
            .putString("login", login)
            .putString("password", password)
            .apply()
    }

    fun getToken(): String? {
        return prefs.getString("auth_token", null)
    }

    fun clearAll() {
        prefs.edit().clear().apply()
    }
}

Migración desde SharedPreferences normales

Para migrar datos existentes desde SharedPreferences no cifradas a EncryptedSharedPreferences, es necesario: leer todos los datos del archivo antiguo, crear una nueva EncryptedSharedPreferences, escribir todos los datos y eliminar el archivo antiguo. Google no proporciona un migrador integrado — el desarrollador lo implementa manualmente.

Comparación con SharedPreferences normales

La elección entre SharedPreferences y EncryptedSharedPreferences depende del tipo de datos almacenados. Para configuraciones de interfaz (tema, idioma, ordenación), las SharedPreferences normales son suficientes. Para información confidencial (tokens, contraseñas, claves), EncryptedSharedPreferences es obligatorio.

Rendimiento

EncryptedSharedPreferences es más lento que el normal debido a las operaciones criptográficas. Escribir un solo valor de cadena toma ~5-15 ms (dependiendo del tamaño de los datos y la aceleración hardware AES). La lectura toma 2-5 ms. Para la mayoría de las aplicaciones esto es imperceptible, pero para operaciones por lotes (migración, restauración) use apply() en lugar de commit().

Seguridad

Las SharedPreferences normales no proporcionan ninguna protección criptográfica: el archivo XML puede ser leído por cualquier proceso con acceso root o mediante adb backup. EncryptedSharedPreferences cifra los datos a nivel de aplicación, y la clave maestra se almacena en Android Keystore con protección hardware opcional (StrongBox).

CaracterísticaSharedPreferencesEncryptedSharedPreferences
AlmacenamientoXML sin cifrarArchivo binario cifrado
CifradoNingunoAES-256 GCM + SIV
Protección de clavesNingunaAndroid Keystore + StrongBox
Rendimiento0.1-1 ms2-15 ms
RecomendaciónConfiguración de UITokens, claves, PII

Cuándo elegir EncryptedSharedPreferences

Use EncryptedSharedPreferences para almacenar: tokens de actualización OAuth, claves API para servicios externos, correo electrónico o número de teléfono del usuario, y configuraciones confidenciales de la aplicación (PIN, indicadores de autenticación). EncryptedSharedPreferences no es adecuado para almacenar datos biométricos o documentos grandes — use EncryptedFile o Room con SQLCipher.

La regla general: si una fuga de datos dañaría al usuario o al negocio — use EncryptedSharedPreferences. Si los datos son solo cosméticos (tema, idioma, ordenación) — SharedPreferences normales. Tiene sentido implementar EncryptedSharedPreferences desde el principio, sin refactorización: reemplazarlo en un proyecto existente requiere migración y manejo de datos antiguos no cifrados.

Recuerde que EncryptedSharedPreferences no protege los datos mientras la aplicación se ejecuta — solo en el disco. Si un atacante tiene acceso a la memoria del proceso, los datos descifrados pueden ser interceptados. Use protección adicional: ProGuard/DexGuard para ofuscación.

Preguntas Frecuentes

¿En qué se diferencia EncryptedSharedPreferences de DataStore?

Jetpack DataStore es una alternativa más moderna a SharedPreferences, basada en Flow y corutinas de Kotlin. DataStore no cifra los datos por defecto, pero puede combinarse con EncryptedSharedPreferences o usarse con cifrado manual a través de Proto DataStore con protocolos criptográficos.

¿Se puede usar EncryptedSharedPreferences para grandes volúmenes de datos?

No se recomienda. EncryptedSharedPreferences está diseñado para volúmenes pequeños (hasta 100-200 KB). Para datos más grandes, use Room con SQLCipher o cifrado de archivos a través de EncryptedFile de la misma biblioteca AndroidX Security.

¿EncryptedSharedPreferences admite migración al actualizar el esquema?

No, no hay migración de esquema automática. Al cambiar la estructura de datos, el desarrollador debe leer manualmente los datos antiguos a través del antiguo KeyGen y escribirlos a través del nuevo. Se recomienda almacenar la versión del esquema en un parámetro separado.

¿Cuál es el nivel de API mínimo requerido?

AndroidX Security 1.0.0 es compatible con API 19+ (Android KitKat). La versión 1.1.0-alpha06 también es compatible con API 19+. StrongBox requiere API 28+ y un dispositivo con soporte hardware (Google Pixel 3+, Samsung Galaxy S9+).

¿Es seguro almacenar el refresh token en EncryptedSharedPreferences?

Sí, el refresh token es uno de los casos de uso principales. Cifrado AES-256 GCM, clave maestra en Keystore, protección biométrica — un nivel suficiente para tokens OAuth. Para tokens de acceso de corta duración también es adecuado, aunque algunos equipos prefieren almacenarlos en memoria.

Resumen

  • EncryptedSharedPreferences — un envoltorio de SharedPreferences con cifrado automático mediante AES-256 GCM (valores) y SIV (claves)
  • Master Key se crea mediante MasterKey.Builder y se almacena en Android Keystore con opciones biométricas y StrongBox
  • La API es totalmente compatible: edit, putString, getString, apply, clear — todo como en SharedPreferences normales
  • Rendimiento: 2-15 ms por operación, imperceptible para el usuario en escenarios estándar
  • Seguridad: el cifrado autenticado (AEAD) evita tanto la lectura como la manipulación de datos
  • Migración desde SharedPreferences normales requiere transferencia manual de datos mediante archivos antiguos y nuevos
  • Use EncryptedSharedPreferences para tokens, claves API, contraseñas y otras configuraciones confidenciales

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