Android Keystore es un proveedor criptográfico que genera y almacena claves de cifrado en un entorno de ejecución aislado (TEE), inaccesible incluso para el sistema operativo. Según AOSP Security Documentation (2025), Keystore se utiliza en más del 80% de las aplicaciones Android del top 100 de Google Play para proteger tokens y cifrar datos. Comprender Android Keystore es fundamental para el almacenamiento seguro de claves en Android.
Puntos Clave
Android Keystore — un componente del sistema de la plataforma Android que proporciona una API para generar, almacenar y usar claves criptográficas en un entorno protegido. A diferencia de las bibliotecas criptográficas de software (Bouncy Castle, Conscrypt), Keystore garantiza que las claves privadas nunca abandonen el área de ejecución aislada.
Keystore apareció por primera vez en Android 4.3 (API 18) como un proveedor de software con soporte RSA. A partir de Android 6.0 (API 23), Keystore recibió soporte de hardware a través de Keymaster Hardware Abstraction Layer (HAL), que delega las operaciones criptográficas al Trusted Execution Environment (TEE) en dispositivos compatibles. Según el Android Compatibility Definition Document (2025), todos los dispositivos con Android 9+ deben admitir Keystore respaldado por hardware a través de TEE o StrongBox.
Las claves en Keystore se identifican mediante un alias — una cadena que se pasa al crear o cargar una clave. Keystore no permite acceder al material bruto de la clave: los métodos getEncoded() devuelven null para las claves creadas en Keystore. Esta es una diferencia fundamental con respecto a las claves de software — un atacante no puede extraer la clave privada incluso con control total del dispositivo.
Keystore está integrado con otros mecanismos de seguridad de Android: autenticación biométrica (BiometricPrompt), cifrado a nivel de archivos (File-Based Encryption) y funciones de verificación SafetyNet / Play Integrity. Las claves pueden configurarse para su eliminación automática bajo ciertas condiciones: cuando se elimina el código de acceso, cuando se añade una nueva huella digital o al vencimiento.
La arquitectura de Android Keystore incluye tres niveles de implementación que difieren en el grado de protección del hardware. El nivel depende de las capacidades del hardware del dispositivo.
TEE (Trusted Execution Environment) — un área aislada que se ejecuta en paralelo con el sistema operativo principal en el mismo procesador. TEE utiliza la tecnología ARM TrustZone, que divide el núcleo físico del procesador en dos virtuales: Normal World (Android) y Secure World (TEE). El código en Secure World tiene acceso a memoria y periféricos inaccesibles desde Normal World.
Cuando una aplicación llama a una operación criptográfica a través de Keystore, la solicitud se pasa a través de Keymaster HAL al TEE, donde la operación se realiza por hardware. El resultado se devuelve a la aplicación, pero la clave privada permanece en la memoria protegida del TEE. TEE está certificado para cumplir con GlobalPlatform TEE Protection Profile y es un requisito obligatorio para Android 9+ en dispositivos con procesadores compatibles con TrustZone.
TEE admite los algoritmos AES/GCM (128, 256 bits), RSA (2048, 4096 bits), EC (P-256, P-384, P-521) y HMAC-SHA256. El rendimiento de TEE es menor que el de la criptografía de software (entre un 20 y un 40%), pero para operaciones típicas (firma JWT, descifrado de clave de sesión), la latencia no supera los 10–50 ms.
StrongBox — un chip de seguridad dedicado, físicamente separado del procesador principal. A diferencia de TEE, que comparte el tiempo de procesador con Android, StrongBox tiene su propia CPU, RAM, generador de números aleatorios verdadero (TRNG) y almacenamiento seguro (memoria programable una sola vez). StrongBox está certificado para Common Criteria EAL 4+ y Secure IC Protection Profile.
StrongBox está disponible en dispositivos con Android 9+ siempre que el chip correspondiente esté presente (por ejemplo, Titan M en Google Pixel, Knox en Samsung Galaxy). El desarrollador habilita StrongBox a través del indicador setIsStrongBoxBacked(true) en KeyGenParameterSpec. Si no hay soporte de hardware disponible, el indicador se ignora y Keystore recurre a TEE.
Limitaciones de StrongBox: admite un conjunto limitado de algoritmos (AES-256, EC P-256, HMAC-SHA256), la cola de operaciones — no más de una a la vez, el número de operaciones — limitado por los recursos del chip. StrongBox no está diseñado para escenarios de alta carga — use TEE para operaciones frecuentes y StrongBox solo para claves críticas (claves maestras de cifrado, claves de firma).
El Keystore basado en software es una implementación de software utilizada en dispositivos sin soporte de hardware para TEE o StrongBox. Las claves se almacenan cifradas en el sistema de archivos, pero la clave privada puede descifrarse temporalmente en la RAM. Keystore de software es menos seguro — un atacante con acceso root puede interceptar la clave en la memoria.
A partir de Android 12 (API 31), Google exige Keystore respaldado por hardware para todos los dispositivos nuevos. Los dispositivos con Android 9–11 pueden tener Keystore de software en modelos económicos. El desarrollador puede verificar el nivel de protección a través de KeyStore.getKeyCharacteristics() — el atributo SECURITY_LEVEL_TRUSTED_ENVIRONMENT o SECURITY_LEVEL_STRONGBOX confirma la protección por hardware.
Android Keystore admite una amplia gama de algoritmos criptográficos, divididos en categorías según el tipo de clave. La elección del algoritmo afecta el rendimiento, la compatibilidad y el nivel de seguridad.
AES (Advanced Encryption Standard) — cifrado simétrico para proteger datos en el dispositivo. Modo recomendado: AES/GCM/NoPadding (256 bits). GCM proporciona cifrado autenticado (AEAD) — verificación de integridad de los datos cifrados. Tamaño del IV (Vector de Inicialización): 12 bytes para GCM. No use AES/ECB — no proporciona la protección adecuada.
RSA (Rivest–Shamir–Adleman) — cifrado asimétrico para proteger claves de sesión y firmas digitales. Tamaño recomendado: 2048 o 4096 bits. Modos: RSA/ECB/PKCS1Padding (cifrado) y RSA/ECB/PKCS1Sign (firma). RSA 1024 se considera obsoleto y no se recomienda para nuevas aplicaciones (NIST SP 800-131A Rev. 2).
EC (Elliptic Curve) — criptografía asimétrica de curva elíptica para firma e intercambio de claves. Curvas compatibles: secp256r1 (P-256, obligatoria), secp384r1 (P-384) y secp521r1 (P-521). EC proporciona una seguridad comparable a RSA con un tamaño de clave significativamente menor. P-256 se recomienda para la mayoría de escenarios: es compatible con todos los dispositivos y proporciona un nivel de seguridad de 128 bits.
HMAC (Hash-based Message Authentication Code) — autenticación simétrica de mensajes. Funciones hash compatibles: SHA-256, SHA-384, SHA-512. HMAC se utiliza para verificar la integridad y autenticidad de los datos, por ejemplo, para verificar solicitudes de webhook o comprobar la integridad de la configuración.
Todos los algoritmos pueden vincularse a la autenticación biométrica a través de KeyGenParameterSpec.Builder.setUserAuthenticationRequired(true). En Android 11+ está disponible el indicador setUserAuthenticationParameters() con un tiempo de espera (en segundos) durante el cual la clave está disponible después de la autenticación biométrica, sin una solicitud repetida.
Veamos ejemplos prácticos de trabajo con Android Keystore en Kotlin: generar una clave AES, cifrar datos y crear un par asimétrico para firmas.
El ejemplo crea una clave AES/GCM de 256 bits con vinculación a autenticación biométrica. La clave no se puede exportar mediante getEncoded().
import android.security.keystore.KeyGenParameterSpec
import android.security.keystore.KeyProperties
import java.security.KeyStore
private val keyStore = KeyStore.getInstance("AndroidKeyStore").apply { load(null) }
fun generateAesKey(alias: String) {
val spec = KeyGenParameterSpec.Builder(
alias,
KeyProperties.PURPOSE_ENCRYPT or
KeyProperties.PURPOSE_DECRYPT
)
.setKeySize(256)
.setBlockModes(KeyProperties.KEY_BLOCK_MODE_GCM)
.setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
.setUserAuthenticationRequired(true)
.setInvalidatedByBiometricEnrollment(true)
.build()
val generator = KeyGenerator.getInstance(
KeyProperties.KEY_ALGORITHM_AES,
"AndroidKeyStore"
)
generator.init(spec)
generator.generateKey()
}
El ejemplo cifra datos usando una clave de Android Keystore. Cipher obtiene la clave por alias, inicializa el cifrado AES/GCM y devuelve los datos cifrados junto con el IV.
fun encryptData(alias: String, plaintext: ByteArray): ByteArray {
val cipher = Cipher.getInstance("AES/GCM/NoPadding")
val secretKey = keyStore.getKey(alias, null) as SecretKey
cipher.init(Cipher.ENCRYPT_MODE, secretKey)
val iv = cipher.getIV()
val encrypted = cipher.doFinal(plaintext)
// IV + datos cifrados
return iv + encrypted
}
fun decryptData(alias: String, ciphertextWithIv: ByteArray): ByteArray {
val iv = ciphertextWithIv.copyOfRange(0, 12)
val encrypted = ciphertextWithIv.copyOfRange(12, ciphertextWithIv.size)
val cipher = Cipher.getInstance("AES/GCM/NoPadding")
val secretKey = keyStore.getKey(alias, null) as SecretKey
val spec = GCMParameterSpec(128, iv)
cipher.init(Cipher.DECRYPT_MODE, secretKey, spec)
return cipher.doFinal(encrypted)
}
El ejemplo crea un par de claves RSA-2048 en Keystore con vinculación a StrongBox. La clave privada se usa para firmar, la clave pública se puede exportar mediante getEncoded().
fun generateRsaKeyPair(alias: String) {
val spec = KeyGenParameterSpec.Builder(
alias,
KeyProperties.PURPOSE_SIGN or
KeyProperties.PURPOSE_VERIFY
)
.setKeySize(2048)
.setSignaturePaddings(
KeyProperties.SIGNATURE_PADDING_RSA_PKCS1
)
.setDigests(KeyProperties.DIGEST_SHA256)
.setIsStrongBoxBacked(true)
.build()
val pair = KeyPairGenerator.getInstance(
KeyProperties.KEY_ALGORITHM_RSA,
"AndroidKeyStore"
).apply { init(spec) }
.generateKeyPair()
// La clave pública se puede exportar
val publicKey = pair.public // X509EncodedKeySpec
}
El uso efectivo de Android Keystore requiere seguir reglas que garanticen la máxima protección mientras se mantiene el rendimiento.
Use KeyGenParameterSpec con los parámetros mínimamente necesarios: especifique solo aquellos propósitos, modos de bloque y rellenos que se usen realmente. Los parámetros redundantes (por ejemplo, PURPOSE_ENCRYPT para una clave que solo se usa para firmar) crean vectores de ataque innecesarios. Android recomienda especificar explícitamente el digest para firmas — SHA256 es el nivel mínimo aceptable (SHA1 está obsoleto).
Vincule las claves a la biométrica para operaciones críticas: setUserAuthenticationRequired(true) garantiza que la clave solo se pueda usar después de la autenticación biométrica. En Android 11+ use setUserAuthenticationParameters() con un tiempo de espera (recomendado 30–60 segundos) para evitar solicitar la biométrica en cada operación dentro de una misma sesión. setInvalidatedByBiometricEnrollment(true) elimina automáticamente la clave cuando se añade una nueva huella digital o rostro — esto evita el acceso con datos biométricos antiguos.
Verifique el nivel de seguridad en la inicialización: use KeyStore.getKeyCharacteristics() para determinar SECURITY_LEVEL. Si el dispositivo solo admite Keystore de software (SECURITY_LEVEL_SOFTWARE), tome una decisión: rechazar la funcionalidad o usar cifrado adicional (por ejemplo, envoltura de clave mediante contraseña de usuario). No confíe en StrongBox si no está garantizado — especifique siempre el indicador setIsStrongBoxBacked(true) y verifique el resultado mediante getKeyCharacteristics.
Rote las claves periódicamente: las claves criptográficas tienen una vida útil recomendada. NIST SP 800-57 recomienda cambiar las claves AES cada 1–2 años, los pares RSA/EC cada 2–3 años. Implemente un mecanismo de rotación de claves: verifique la fecha de creación de la clave al iniciar la aplicación (KeyGenParameterSpec.Builder.setKeyValidityStart/End) y genere una nueva clave cuando expire. Los datos antiguos cifrados con la clave anterior deben descifrarse y volverse a cifrar con la nueva.
No use Keystore para datos grandes: Keystore está diseñado para almacenar claves (unos pocos cientos de bytes), no para cifrar archivos grandes. Para el cifrado de datos, use el esquema: genere una clave AES aleatoria (DEK — Data Encryption Key), cifre los datos con esta clave y cifre el DEK con una clave de Keystore (KEK — Key Encryption Key). Android EncryptedSharedPreferences usa exactamente este esquema: clave maestra en Keystore, datos — AES-256 GCM.
Preguntas Frecuentes
No, Android Keystore está diseñado para que la clave privada nunca salga de TEE o StrongBox. El método getEncoded() devuelve null para las claves creadas en Keystore. La clave solo se puede usar a través de Cipher, Signature o Mac API — el material bruto es inaccesible.
TEE (TrustZone) — aislamiento virtual en el mismo procesador, utiliza compartición de tiempo. StrongBox — un chip separado con su propia CPU y memoria. StrongBox es más seguro (Common Criteria EAL 4+), pero más lento y admite menos algoritmos. TEE es adecuado para operaciones frecuentes, StrongBox para claves críticas.
Use KeyStore.getKeyCharacteristics() después de generar una clave con el indicador setIsStrongBoxBacked(true). El atributo SECURITY_LEVEL_STRONGBOX confirma la compatibilidad de hardware. Si el dispositivo no admite StrongBox, Keystore recurre a TEE sin error — debe verificar explícitamente el nivel de seguridad.
Las claves en Keystore se eliminan automáticamente cuando se desinstala la aplicación del dispositivo. En Android 10+ las claves pueden persistir si la aplicación tiene el indicador allowBackup=true en su manifiesto, pero no estarán disponibles después de reinstalar. Se recomienda generar las claves nuevamente en una instalación limpia.
No, Android Keystore está vinculado al hardware de un dispositivo específico. Una clave generada en el TEE de un dispositivo no se puede transferir a otro. Para el cifrado multiplataforma, use el esquema: Keystore protege la clave en el dispositivo y las claves de sesión se transmiten a través de una API segura mediante cifrado asimétrico.
Resumen
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.
Lea también