KeyStore (Android): conceptos clave, API y funcionamiento del almacenamiento criptográfico

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

KeyStore (Android) es una implementación del proveedor criptográfico Java Cryptography Architecture (JCA) integrada en Android para el almacenamiento seguro de claves con capacidad de aislamiento por hardware. Desde Android 4.3 (API 18), KeyStore admite claves de hardware a través de Keymaster HAL, y a partir de Android 9 (API 28), StrongBox Keymaster para claves en un Secure Element dedicado. Según la Documentación de seguridad de Android, el proveedor “AndroidKeyStore” reemplaza a Bouncy Castle u OpenSSL KeyStore estándar, proporcionando protección a nivel de sistema contra la extracción no autorizada de claves.

Puntos clave

  • Android KeyStore es un proveedor JCA para almacenamiento de claves con soporte TEE, StrongBox y protección biométrica
  • KeyGenParameterSpec define el algoritmo, propósito, digest, padding y biometría al crear una clave
  • Keymaster HAL implementa operaciones criptográficas de hardware en los niveles Software, TEE y StrongBox
  • Key Attestation (API 28+) permite al servidor verificar que la clave se creó en un entorno de hardware de Android KeyStore
  • Alias de clave es una cadena mediante la cual la aplicación accede a la clave en Keystore; un alias corresponde a una clave

¿Qué es KeyStore en Android?

KeyStore en Android no es una aplicación o archivo separado, sino un proveedor criptográfico que implementa la interfaz java.security.KeyStore. Proporciona una API unificada para almacenar y usar claves privadas, claves simétricas y certificados de CA de confianza. El proveedor está registrado bajo el nombre “AndroidKeyStore” y es accesible mediante el KeyStore.getInstance() estándar.

Evolución de Android KeyStore

Antes de Android 4.3, las operaciones criptográficas se realizaban mediante Bouncy Castle. Android 4.3 introdujo Keymaster HAL 1.0, permitiendo el uso de TEE en ARM TrustZone. Android 6.0 (API 23) agregó Keymaster 2.0 con autenticación biométrica por hardware. Android 9 (API 28) presentó Keymaster 4.0 y StrongBox Keymaster para un Secure Element dedicado.

Cada versión de Keymaster agrega nuevas capacidades y mejora el aislamiento de claves. Los dispositivos modernos (2022+) deben admitir Keymaster 4.0 para la certificación de Google Mobile Services, lo que garantiza la disponibilidad de TEE para todas las aplicaciones de Android.

Arquitectura y componentes

Android KeyStore consta de tres capas: API de Java (KeyStore, KeyPairGenerator), proceso de sistema keystore (C++, se ejecuta como servicio del sistema) y Keymaster HAL (biblioteca en TEE o Secure Element). La aplicación llama a la API, el servicio keystore enruta la solicitud a Keymaster y la operación se realiza en el entorno seguro.

Todas las claves privadas se almacenan en TEE y no se pueden leer desde el espacio de usuario. Incluso el servicio de keystore del sistema no tiene acceso a las claves sin procesar, solo a los identificadores que apuntan a las claves dentro de Keymaster.

¿Cómo funciona KeyStore como proveedor criptográfico?

Android KeyStore implementa la interfaz estándar de proveedor de servicios JCA. Cuando una aplicación llama a Cipher.getInstance(“RSA/ECB/PKCS1Padding”, “AndroidKeyStore”), el Proveedor de seguridad de Android delega la operación a Keymaster a través de la cadena: Java → JNI → servicio keystore → Keymaster HAL.

Registro del proveedor

El proveedor AndroidKeyStore se registra automáticamente al iniciar el proceso. Su prioridad es mayor que la de Bouncy Castle o Conscrypt. Por lo tanto, al llamar a KeyStore.getInstance() sin especificar un proveedor, se devuelve AndroidKeyStore en la mayoría de los casos. Para una invocación explícita, use KeyStore.getInstance(“AndroidKeyStore”).

Cada aplicación de Android tiene un contenedor aislado en KeyStore. Las aplicaciones con el mismo UID (shared userId) pueden compartir el acceso a ciertas claves, pero la configuración estándar garantiza que la aplicación A no pueda leer las claves de la aplicación B.

Métodos de KeyStore y sus particularidades

load(null) — inicialización de KeyStore. El parámetro siempre es null para AndroidKeyStore. setEntry — guarda una clave con KeyProtection especificada (propósitos, digest, padding). getEntry — obtiene KeyStore.PrivateKeyEntry, SecretKeyEntry o TrustedCertificateEntry. containsAlias — verifica si existe una clave. deleteEntry — elimina una clave de forma permanente.

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

object KeyStoreManager {
    private val keyStore by lazy {
        KeyStore.getInstance("AndroidKeyStore").apply { load(null) }
    }

    fun createRsaKey(alias: String) {
        val spec = KeyGenParameterSpec.Builder(alias,
            KeyProperties.PURPOSE_SIGN or KeyProperties.PURPOSE_VERIFY
        ).setKeySize(2048)
         .setDigests(KeyProperties.DIGEST_SHA256)
         .setSignaturePaddings(KeyProperties.SIGN_PADDING_RSA_PKCS1)
         .build()

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

Algoritmos y tipos de clave compatibles

Android KeyStore admite un amplio conjunto de algoritmos criptográficos, que varía según la versión de Keymaster HAL en el dispositivo. Un desarrollador puede obtener la lista de algoritmos compatibles a través de KeyGenParameterSpec.Builder al intentar la generación; los parámetros incompatibles lanzan InvalidAlgorithmParameterException.

Algoritmos asimétricos

RSA (1024–4096 bits) — para firma (PKCS1, PSS con SHA-1/SHA-256/SHA-384/SHA-512) y cifrado (OAEP con SHA-1/SHA-256). EC (P-224, P-256, P-384, P-521) — para firma ECDSA y acuerdo de claves ECDH. X25519 y Ed25519 — desde Android 12 (API 31) para protocolos criptográficos modernos.

Para claves asimétricas, genere siempre dentro de Keymaster, NUNCA importe claves privadas. Las claves privadas importadas no están protegidas por hardware; se almacenan en la capa de software y son vulnerables si el proceso de la aplicación se ve comprometido.

Algoritmos simétricos

AES (128, 256 bits) — para cifrado simétrico en modos CBC, CTR, GCM. HMAC (SHA-1, SHA-256, SHA-512) — para autenticación de mensajes. ChaCha20 (Android 12+) — para cifrado de flujo de alto rendimiento con autenticación Poly1305.

AlgoritmoKeymasterPropósitoAPI
RSAKM 1.0+Firma, Cifrado18+
ECKM 1.0+ECDSA, ECDH18+
AESKM 2.0+Cifrado simétrico23+
HMACKM 2.0+Código de autenticación23+
ChaCha20KM 3.0+Cifrado de flujo31+
X25519/Ed25519KM 3.0+Intercambio de claves31+

Tipos de clave y su serialización

KeyStore.PrivateKeyEntry — contiene una clave privada (no exportable) y una cadena de certificados. KeyStore.SecretKeyEntry — para claves simétricas. KeyStore.TrustedCertificateEntry — para certificados de CA de confianza. Las claves públicas se pueden exportar mediante keyStore.getCertificate(alias).publicKey.

Ejemplos de generación y uso de claves

Veamos un escenario completo: generar una clave AES para cifrado de datos y generar una clave EC para firma con protección biométrica. Ambas claves se crean dentro de Android KeyStore con soporte de hardware.

Generación de una clave AES para cifrado

Una clave AES se crea mediante KeyGenerator con KeyGenParameterSpec. Parámetros: PURPOSE_ENCRYPT + PURPOSE_DECRYPT, BLOCK_MODE_GCM (modo recomendado con autenticación), ENCRYPTION_PADDING_NONE (no se necesita padding para GCM).

kotlin
import javax.crypto.KeyGenerator
import javax.crypto.Cipher
import javax.crypto.spec.GCMParameterSpec

fun generateAndEncrypt(alias: String, plainText: ByteArray): ByteArray {
    val spec = KeyGenParameterSpec.Builder(alias,
        KeyProperties.PURPOSE_ENCRYPT or KeyProperties.PURPOSE_DECRYPT
    ).setBlockModes(KeyProperties.BLOCK_MODE_GCM)
     .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
     .setKeySize(256)
     .build()

    val kg = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES, "AndroidKeyStore")
    kg.initialize(spec)
    kg.generateKey()

    val cipher = Cipher.getInstance("AES/GCM/NoPadding")
    cipher.init(Cipher.ENCRYPT_MODE, getKeyFromStore(alias))
    return cipher.doFinal(plainText)
}

Firma con protección biométrica

Una clave EC con userAuthenticationRequired=true requiere autenticación del usuario antes de cada operación de firma. Para ello se utiliza BiometricPrompt con CryptoObject que contiene el objeto Signature. Después de la verificación biométrica exitosa, Keymaster permite la operación.

kotlin
fun createBiometricSignKey(alias: String) {
    val spec = KeyGenParameterSpec.Builder(alias,
        KeyProperties.PURPOSE_SIGN
    ).setAlgorithmParameterSpec(
        ECGenParameterSpec("secp256r1")
    ).setDigests(KeyProperties.DIGEST_SHA256)
     .setUserAuthenticationRequired(true)
     .setInvalidatedByBiometricEnrollment(true)
     .build()

    val kpg = KeyPairGenerator.getInstance(
        KeyProperties.KEY_ALGORITHM_EC,
        "AndroidKeyStore"
    )
    kpg.initialize(spec)
    kpg.generateKeyPair()
}

KeyStore y seguridad en el dispositivo

Android KeyStore proporciona garantías de seguridad a nivel de hardware que los KeyStore basados en software (JKS, BKS) no pueden ofrecer. Las claves están protegidas a nivel de SoC, e incluso el control total sobre el espacio de usuario de Android no permite extraer la clave privada.

Key Attestation (Android 8.1+)

Key Attestation es un mecanismo que permite a una aplicación (y al servidor) verificar el entorno en el que se creó una clave. Android Keystore firma un certificado que contiene una lista de características de la clave: algoritmo, tamaño, propósitos, hardware-backed (True/False), origen (GENERATED, IMPORTED). El servidor verifica la cadena de certificados hasta el certificado raíz de Google.

Esto es fundamental para las aplicaciones financieras: el servidor puede exigir que la clave se haya creado en un entorno de hardware (Hardware-Backed = True) y rechazar claves creadas en Keystore de software. Key Attestation previene ataques en los que un atacante reemplaza el Keystore por un emulador.

Invalidación de claves al cambiar la biometría

setInvalidatedByBiometricEnrollment(true) significa que Keymaster eliminará automáticamente la clave cuando se modifiquen o eliminen las plantillas biométricas del usuario. Esto protege contra ataques en los que un atacante agrega su huella digital a una cuenta existente. Después de agregar una nueva huella, las claves antiguas se vuelven inaccesibles.

El contador de intentos fallidos de autenticación biométrica también es gestionado por Keymaster. Después de maxBiometricAttempt (configurable por el fabricante, normalmente 5), Keymaster bloquea todas las operaciones con claves biométricas durante 30 segundos. Después de 10 intentos fallidos, hasta que se ingrese la contraseña del dispositivo (PIN secreto).

Preguntas frecuentes

¿Cuál es la diferencia entre Android KeyStore y Bouncy Castle KeyStore?

Bouncy Castle (BKS) es un KeyStore de software que almacena claves en un archivo protegido por contraseña. Android KeyStore utiliza aislamiento por hardware TEE/StrongBox. Las claves BKS se pueden extraer con acceso root, las claves de Android KeyStore no. BKS es adecuado para certificados de CA, Android KeyStore es para claves privadas.

¿Puedo usar la misma clave para cifrado y firma?

Sí, si especifica PURPOSE_ENCRYPT o PURPOSE_DECRYPT o PURPOSE_SIGN o PURPOSE_VERIFY al generar la clave. Sin embargo, la mejor práctica es crear claves separadas para diferentes operaciones. Esto limita el daño si una clave se ve comprometida y sigue el principio de mínimo privilegio.

¿Cómo saber si una clave está respaldada por hardware en Android KeyStore?

Utilice KeyStore.getKeyCharacteristics(alias), disponible a través de android.security.keystore. El método devuelve un conjunto de banderas: FLAG_HARDWARE — clave en TEE, FLAG_SECURE_ELEMENT — clave en StrongBox. Si no hay banderas, la clave es solo software.

¿Qué sucede cuando se eliminan todas las plantillas biométricas?

Todas las claves creadas con setInvalidatedByBiometricEnrollment(true) serán invalidadas automáticamente por Keymaster. Al intentar usarlas, la aplicación recibirá KeyPermanentlyInvalidatedException. Los datos cifrados con estas claves se perderán permanentemente.

¿Admite Android KeyStore la copia de seguridad de claves?

Las claves de hardware (en TEE/StrongBox) no admiten copia de seguridad, están vinculadas a un dispositivo específico. Las claves de software pueden incluirse en la copia de seguridad de Google Drive. Para transferir datos entre dispositivos, cifre los datos en el servidor y descifrelos en el nuevo dispositivo.

Resumen

  • Android KeyStore — proveedor JCA para almacenamiento de claves aislado por hardware mediante Keymaster HAL en TEE/StrongBox
  • KeyGenParameterSpec configura algoritmo, tamaño, propósitos, digest, biometría y restricciones temporales de la clave
  • RSA (KM 1.0+), EC (KM 1.0+), AES (KM 2.0+), ChaCha20 (KM 3.0+) — algoritmos compatibles con diferentes niveles de Keymaster
  • Key Attestation (API 28+) permite al servidor verificar el origen de hardware de la clave
  • Protección biométrica de claves mediante setUserAuthenticationRequired + BiometricPrompt con CryptoObject
  • Invalidación de claves al cambiar la biometría previene el uso no autorizado de huellas agregadas
  • Use Android KeyStore para generar y almacenar claves criptográficas con protección de hardware 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