Keystore (Android): qué es, arquitectura y principios de funcionamiento

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

Android Keystore es un mecanismo de sistema en Android para almacenar de forma segura claves criptográficas en aislamiento de hardware. El sistema utiliza Trusted Execution Environment (TEE) en dispositivos con ARM TrustZone o un Secure Element dedicado para proteger las claves a nivel de chip. Según Android Open Source Project, Keystore admite los algoritmos RSA, EC, AES y HMAC con generación de claves directamente en el entorno seguro.

Puntos clave

  • Android Keystore es un proveedor KeyStore que aísla las claves criptográficas del espacio de usuario de Android
  • Las claves se generan dentro de TEE o Secure Element y nunca abandonan el entorno seguro en texto plano
  • Android 9+ añade KeyGenParameterSpec.Builder con parámetros: purpose, digest, padding, userAuthenticationRequired
  • La protección biométrica de claves requiere confirmación del usuario mediante BiometricPrompt antes de cada operación
  • Keymaster HAL es una capa de abstracción de hardware que implementa operaciones criptográficas en TEE o Secure Element

¿Qué es Android Keystore?

Android Keystore es un proveedor criptográfico implementado en Android desde API 1 (Android 1.0), pero la compatibilidad completa con hardware apareció con Android 4.3 (API 18). Keystore resuelve el problema del almacenamiento seguro de claves privadas de modo que incluso si el sistema operativo se ve comprometido, un atacante no pueda extraer las claves en texto plano.

Arquitectura de KeyStore en Android

La arquitectura de Android Keystore consta de tres niveles: la API de aplicación (java.security.KeyStore), el servicio del sistema (keystore daemon) y el nivel de hardware (Keymaster HAL). La aplicación accede a través de la API estándar Java Cryptography Architecture (JCA), y el servicio del sistema enruta las solicitudes a Keymaster que se ejecuta en TEE.

Todas las operaciones criptográficas con claves (firma, descifrado) se realizan dentro de TEE o Secure Element. Las claves nunca abandonan el entorno seguro: la aplicación recibe solo un identificador (alias) para referenciar la clave. Esta es una diferencia fundamental con los KeyStore de software, donde las claves son potencialmente accesibles en la memoria del proceso.

Diferencia con Java KeyStore

El JKS (Java KeyStore) estándar o BKS (Bouncy Castle) almacenan claves en archivos protegidos por contraseña. Android Keystore almacena claves en aislamiento de hardware, donde están protegidas incluso del usuario root. JKS es vulnerable al acceso directo al sistema de archivos; Android Keystore no.

Otra diferencia: en Android Keystore, las claves tienen parámetros de uso estrictos (purpose — solo sign/verify/encrypt/decrypt) especificados en el momento de la generación. No se pueden cambiar después, lo que evita el mal uso de la clave.

¿Cómo funciona Android Keystore?

Al crear una nueva clave, la aplicación llama a KeyPairGenerator o KeyGenerator con KeyGenParameterSpec, que contiene todos los parámetros de la clave futura. El sistema pasa la solicitud a Keymaster HAL, que genera la clave dentro de TEE y devuelve un identificador.

Proceso de generación de claves

El método KeyGenParameterSpec.Builder acepta parámetros obligatorios: nombre de la clave en Keystore, propósito (PURPOSE_SIGN, PURPOSE_ENCRYPT), algoritmo (RSA, EC, AES). Adicionalmente: digest (SHA-256), padding (PKCS7), userAuthenticationRequired (biometría), keyValidityStart/End (restricciones de tiempo).

Después de establecer los parámetros, KeyPairGenerator.generateKeyPair() devuelve un KeyPair, donde PrivateKey es un objeto que delega operaciones a Keymaster. La clave pública se puede extraer, la privada no. Existe solo dentro de TEE.

kotlin
import java.security.KeyPairGenerator
import android.security.keystore.KeyGenParameterSpec
import android.security.keystore.KeyProperties

fun generateKey(alias: String) {
    val spec = KeyGenParameterSpec.Builder(alias,
        KeyProperties.PURPOSE_SIGN or KeyProperties.PURPOSE_VERIFY
    ).setDigests(KeyProperties.DIGEST_SHA256)
     .setSignaturePaddings(KeyProperties.SIGN_PADDING_RSA_PKCS1)
     .setUserAuthenticationRequired(true)
     .build()

    val kpGen = KeyPairGenerator.getInstance(
        KeyProperties.KEY_ALGORITHM_RSA,
        "AndroidKeyStore"
    )
    kpGen.initialize(spec)
    kpGen.generateKeyPair()
}

Firma y verificación

Signature para ECDSA o RSA-PSS se crea a través de la API estándar: Signature.getInstance(algorithm).initSign(privateKey). La operación de firma se realiza en TEE: la aplicación pasa datos, Keymaster los firma en hardware y devuelve la firma. La clave y los datos no se mezclan en la memoria compartida.

Para la protección biométrica, el usuario debe autenticarse mediante BiometricPrompt antes de firmar. Sin autenticación exitosa, Keymaster no realiza la operación y devuelve CryptoAuthenticationException.

kotlin
import java.security.KeyStore
import java.security.Signature
import androidx.biometric.BiometricPrompt

fun signWithBiometric(alias: String) {
    val ks = KeyStore.getInstance("AndroidKeyStore")
    ks.load(null)
    val entry = ks.getEntry(alias, null) as KeyStore.PrivateKeyEntry
    val signature = Signature.getInstance("SHA256withRSA")
    signature.initSign(entry.privateKey)
    // BiometricPrompt con CryptoObject(signature) solicita FaceID/PIN
}

Tipos de almacenamiento KeyStore

Android admite dos modos de almacenamiento de claves: software (en dispositivos sin TEE) y hardware (en dispositivos con TEE o Secure Element). El modo depende de las capacidades del SoC y la versión de Android.

KeyStore de software (solo software)

En dispositivos sin Trusted Execution Environment (anteriores a Android 4.3 o SoCs económicos), las claves se almacenan cifradas usando una clave maestra derivada de la contraseña de la pantalla de bloqueo. Este modo es menos seguro: las claves son accesibles en la memoria del proceso durante las operaciones criptográficas.

El nivel de protección se basa en el cifrado del archivo KeyStore con AES-256-GCM. La clave de cifrado se genera a partir de la contraseña o PIN del usuario mediante Scrypt (PBKDF2 con un alto número de iteraciones).

KeyMaster de hardware (TEE/Secure Element)

En dispositivos modernos se utiliza Keymaster 4.x en TEE (ARM TrustZone). Las claves se generan, almacenan y utilizan exclusivamente dentro de TrustZone. Incluso el kernel de Linux no tiene acceso a las claves privadas, solo Keymaster HAL puede realizar operaciones.

Secure Element (por ejemplo, eSE en Samsung Knox o StrongBox en Google Pixel 3+) es un chip separado con su propio procesador y memoria. Está certificado Common Criteria EAL 4+ y proporciona el máximo nivel de protección, incluida la protección contra manipulación física.

TipoUbicación de almacenamientoNivel de protecciónDisponible desde API
SoftwareArchivo /data/misc/keystoreMedio (AES-256)API 1+
Keymaster 3TEE (TrustZone)AltoAPI 23+
Keymaster 4TEE + Secure I/OMuy altoAPI 28+
StrongBoxSecure Element de hardwareMáximoAPI 28+, opcional

Trabajar con la API KeyStore

Android Keystore está integrado en Java Cryptography Architecture (JCA). Para acceder al proveedor se utiliza KeyStore.getInstance("AndroidKeyStore"). La API está disponible desde API 18.

Creación y carga de KeyStore

El método KeyStore.load(null) carga el contenedor KeyStore de la aplicación. No se requiere contraseña: Android utiliza el contexto de la aplicación y su UID para el control de acceso. Cada aplicación ve solo sus propias entradas a menos que se use un UID compartido.

Los métodos setEntry y getEntry funcionan con KeyStore.PrivateKeyEntry, SecretKeyEntry o TrustedCertificateEntry. El parámetro ProtectionParameter es siempre null para Android Keystore (la protección se implementa a nivel del sistema).

kotlin
import java.security.KeyStore
import java.security.cert.Certificate
import android.security.keystore.KeyProtection

fun storeSecretKey(alias: String, key: SecretKey) {
    val ks = KeyStore.getInstance("AndroidKeyStore")
    ks.load(null)
    val prot = KeyProtection.Builder(
        KeyProperties.PURPOSE_ENCRYPT or KeyProperties.PURPOSE_DECRYPT
    ).setBlockModes(KeyProperties.BLOCK_MODE_GCM)
     .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
     .setUserAuthenticationRequired(true)
     .build()
    ks.setEntry(alias, KeyStore.SecretKeyEntry(key), prot)
}

Verificación del tipo de almacenamiento

Usando KeyCharacteristics, se puede determinar en qué entorno se almacena la clave: KeyStore de software, TEE o StrongBox. El método getKeyCharacteristics() devuelve un conjunto de banderas: FLAG_HARDWARE (keymaster), FLAG_SECURE_ELEMENT (StrongBox), FLAG_TRUSTED_USER_PRESENCE_REQUIRED (biometría).

Algoritmos y seguridad

Android Keystore admite una amplia gama de algoritmos criptográficos divididos en tres categorías: asimétricos, simétricos y MAC. La compatibilidad con algoritmos específicos depende de la versión de Keymaster HAL.

Algoritmos compatibles

RSA (1024–4096 bits) — para firma (PKCS1, PSS) y cifrado (OAEP, PKCS1). EC (P-224, P-256, P-384, P-521) — para firma ECDSA y acuerdo de claves ECDH. AES (128, 256 bits) — para cifrado simétrico en modos CBC, CTR, GCM. HMAC (SHA1, SHA256, SHA512) — para autenticación de mensajes.

Para cada clave se especifica setPurposes para restringir las operaciones posibles. Una clave RSA con PURPOSE_SIGN no se puede usar para cifrado, incluso si un atacante tiene acceso a la API. Esto es una aplicación del uso de claves a nivel de hardware.

Protección contra compromiso

Keymaster incluye un contador de intentos fallidos de autenticación biométrica. Después de un número especificado de fallos (configurable mediante setInvalidatedByBiometricEnrollment), la clave se vuelve no disponible y requiere eliminación/regeneración. Cuando se eliminan todas las plantillas biométricas, todas las claves con userAuthenticationRequired=true se invalidan automáticamente.

También se admite Key Attestation (Android 8.1+): a solicitud de la aplicación, Keymaster firma un certificado con información sobre las características de la clave (hardware/software, algoritmo, propósitos). El servidor puede verificar este certificado para confirmar que la clave se creó en un entorno confiable.

Preguntas frecuentes

¿Cuál es la diferencia entre Android Keystore y Java KeyStore?

Java KeyStore almacena claves en un archivo protegido por contraseña (JKS, BKS). Android Keystore utiliza aislamiento de hardware mediante TEE o Secure Element. Java KeyStore es vulnerable al acceso root; Android Keystore no, porque las claves privadas nunca abandonan el entorno seguro.

¿Se puede importar una clave existente en Android Keystore?

Sí, mediante KeyStore.setEntry con KeyProtection. Sin embargo, la clave importada no tendrá protección de hardware — se almacenará en el Keystore de software, cifrada con una clave maestra. Para máxima seguridad, siempre genere claves dentro de Keystore.

¿Cómo verificar si un dispositivo admite KeyStore de hardware?

Use KeyChain.isBoundKeyAlgorithm o verifique KeyCharacteristics después de la generación de la clave. La presencia de FLAG_HARDWARE en las características significa que la clave se creó en TEE. También puede consultar android.security.keystore.isHardwareBacked().

¿Qué sucede con las claves cuando se desinstala la aplicación?

Cuando se desinstala la aplicación, Android elimina todas sus claves de Keystore. Los datos se pierden irreversiblemente. En la reinstalación, la aplicación debe generar nuevas claves. La copia de seguridad de claves a través de TEE es arquitectónicamente imposible.

¿Cómo protege KeyStore contra ataques de depuración?

En un dispositivo bloqueado, Keymaster no realiza ninguna operación. Las claves con userAuthenticationRequired=true requieren confirmación biométrica cada vez. Incluso con acceso root, un atacante no puede llamar a Keymaster directamente — solo a través del servicio Android Keystore.

Resumen

  • Android Keystore es un proveedor criptográfico JCA con aislamiento de claves por hardware mediante TEE o Secure Element
  • Las claves se generan dentro de TrustZone y nunca abandonan el entorno seguro en texto plano
  • KeyGenParameterSpec define los parámetros de la clave: purpose, digest, padding, userAuthenticationRequired, keyValidity
  • Keymaster HAL implementa tres niveles: software, TEE (Keymaster 3/4) y StrongBox (Secure Element de hardware)
  • La protección biométrica de claves se proporciona mediante setUserAuthenticationRequired y BiometricPrompt con CryptoObject
  • Key Attestation (API 28+) permite la verificación en el servidor de que la clave se creó en un entorno de hardware
  • Use Android Keystore para almacenar claves privadas para firma, cifrado y autenticación en aplicaciones Android

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