KeyStore (Android): các khái niệm chính, API và cách hoạt động của kho lưu trữ mật mã

Tác giả: IT Sectr Đã đăng: 2026-03-14 Thời gian đọc: 10 phút

KeyStore (Android) là một triển khai của nhà cung cấp mật mã Java Cryptography Architecture (JCA) được tích hợp vào Android để lưu trữ khóa an toàn với khả năng cách ly phần cứng. Từ Android 4.3 (API 18), KeyStore hỗ trợ khóa phần cứng thông qua Keymaster HAL và từ Android 9 (API 28) hỗ trợ StrongBox Keymaster cho khóa trong Secure Element chuyên dụng. Theo Tài liệu bảo mật Android, nhà cung cấp “AndroidKeyStore” thay thế Bouncy Castle hoặc OpenSSL KeyStore tiêu chuẩn, cung cấp khả năng bảo vệ ở cấp hệ thống chống lại việc trích xuất khóa trái phép.

Những điểm chính

  • Android KeyStore là nhà cung cấp JCA để lưu trữ khóa với hỗ trợ TEE, StrongBox và bảo vệ sinh trắc học
  • KeyGenParameterSpec xác định thuật toán, mục đích, digest, padding và sinh trắc học khi tạo khóa
  • Keymaster HAL triển khai các thao tác mật mã phần cứng ở các cấp Software, TEE và StrongBox
  • Key Attestation (API 28+) cho phép máy chủ xác minh rằng khóa được tạo trong môi trường phần cứng của Android KeyStore
  • Bí danh khóa là một chuỗi mà ứng dụng sử dụng để truy cập khóa trong Keystore; một bí danh tương ứng với một khóa

KeyStore trong Android là gì?

KeyStore trong Android không phải là một ứng dụng hay tệp riêng biệt, mà là một nhà cung cấp mật mã triển khai giao diện java.security.KeyStore. Nó cung cấp một API thống nhất để lưu trữ và sử dụng khóa riêng tư, khóa đối xứng và chứng chỉ CA đáng tin cậy. Nhà cung cấp được đăng ký với tên “AndroidKeyStore” và có thể truy cập thông qua KeyStore.getInstance() tiêu chuẩn.

Sự phát triển của Android KeyStore

Trước Android 4.3, các thao tác mật mã được thực hiện thông qua Bouncy Castle. Android 4.3 giới thiệu Keymaster HAL 1.0, cho phép sử dụng TEE trên ARM TrustZone. Android 6.0 (API 23) bổ sung Keymaster 2.0 với xác thực vân tay dựa trên phần cứng. Android 9 (API 28) giới thiệu Keymaster 4.0 và StrongBox Keymaster cho Secure Element chuyên dụng.

Mỗi phiên bản Keymaster bổ sung các khả năng mới và cải thiện khả năng cách ly khóa. Các thiết bị hiện đại (2022+) phải hỗ trợ Keymaster 4.0 để được chứng nhận Google Mobile Services, đảm bảo tính khả dụng của TEE cho tất cả các ứng dụng Android.

Kiến trúc và thành phần

Android KeyStore bao gồm ba lớp: Java API (KeyStore, KeyPairGenerator), tiến trình hệ thống keystore (C++, chạy như một dịch vụ hệ thống) và Keymaster HAL (thư viện trong TEE hoặc Secure Element). Ứng dụng gọi API, dịch vụ keystore định tuyến yêu cầu đến Keymaster và thao tác được thực thi trong môi trường an toàn.

Tất cả các khóa riêng tư được lưu trữ trong TEE và không thể đọc từ không gian người dùng. Ngay cả dịch vụ keystore hệ thống cũng không có quyền truy cập vào khóa thô — chỉ có các handle trỏ đến khóa bên trong Keymaster.

KeyStore hoạt động như nhà cung cấp mật mã như thế nào?

Android KeyStore triển khai giao diện nhà cung cấp dịch vụ JCA tiêu chuẩn. Khi một ứng dụng gọi Cipher.getInstance(“RSA/ECB/PKCS1Padding”, “AndroidKeyStore”), Nhà cung cấp bảo mật Android ủy quyền thao tác cho Keymaster thông qua chuỗi: Java → JNI → dịch vụ keystore → Keymaster HAL.

Đăng ký nhà cung cấp

Nhà cung cấp AndroidKeyStore được đăng ký tự động khi tiến trình khởi động. Ưu tiên của nó cao hơn Bouncy Castle hoặc Conscrypt. Do đó, khi gọi KeyStore.getInstance() mà không chỉ định nhà cung cấp, AndroidKeyStore được trả về trong hầu hết các trường hợp. Để gọi rõ ràng, hãy sử dụng KeyStore.getInstance(“AndroidKeyStore”).

Mỗi ứng dụng Android có một vùng chứa cách ly trong KeyStore. Các ứng dụng có cùng UID (shared userId) có thể chia sẻ quyền truy cập vào một số khóa nhất định, nhưng cấu hình tiêu chuẩn đảm bảo rằng ứng dụng A không thể đọc khóa của ứng dụng B.

Các phương thức của KeyStore và đặc điểm của chúng

load(null) — khởi tạo KeyStore. Tham số luôn là null đối với AndroidKeyStore. setEntry — lưu khóa với KeyProtection được chỉ định (mục đích, digest, padding). getEntry — truy xuất KeyStore.PrivateKeyEntry, SecretKeyEntry hoặc TrustedCertificateEntry. containsAlias — kiểm tra xem khóa có tồn tại không. deleteEntry — xóa khóa vĩnh viễn.

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()
    }
}

Các thuật toán và loại khóa được hỗ trợ

Android KeyStore hỗ trợ một bộ thuật toán mật mã đa dạng, thay đổi tùy theo phiên bản Keymaster HAL trên thiết bị. Nhà phát triển có thể lấy danh sách các thuật toán được hỗ trợ thông qua KeyGenParameterSpec.Builder khi cố gắng tạo — các tham số không tương thích sẽ ném InvalidAlgorithmParameterException.

Thuật toán bất đối xứng

RSA (1024–4096 bit) — để ký (PKCS1, PSS với SHA-1/SHA-256/SHA-384/SHA-512) và mã hóa (OAEP với SHA-1/SHA-256). EC (P-224, P-256, P-384, P-521) — để ký ECDSA và thỏa thuận khóa ECDH. X25519Ed25519 — từ Android 12 (API 31) cho các giao thức mật mã hiện đại.

Đối với khóa bất đối xứng, hãy luôn tạo bên trong Keymaster, KHÔNG BAO GIỜ nhập khóa riêng tư. Khóa riêng tư được nhập không được bảo vệ bằng phần cứng — chúng được lưu trữ trong lớp phần mềm và dễ bị tổn thương nếu tiến trình ứng dụng bị xâm phạm.

Thuật toán đối xứng

AES (128, 256 bit) — để mã hóa đối xứng ở các chế độ CBC, CTR, GCM. HMAC (SHA-1, SHA-256, SHA-512) — để xác thực thông điệp. ChaCha20 (Android 12+) — để mã hóa luồng hiệu suất cao với xác thực Poly1305.

Thuật toánKeymasterMục đíchAPI
RSAKM 1.0+Ký, Mã hóa18+
ECKM 1.0+ECDSA, ECDH18+
AESKM 2.0+Mã hóa đối xứng23+
HMACKM 2.0+Mã xác thực23+
ChaCha20KM 3.0+Mã hóa luồng31+
X25519/Ed25519KM 3.0+Trao đổi khóa31+

Các loại khóa và tuần tự hóa

KeyStore.PrivateKeyEntry — chứa khóa riêng tư (không thể xuất) và chuỗi chứng chỉ. KeyStore.SecretKeyEntry — cho khóa đối xứng. KeyStore.TrustedCertificateEntry — cho chứng chỉ CA đáng tin cậy. Khóa công khai có thể được xuất thông qua keyStore.getCertificate(alias).publicKey.

Ví dụ về tạo và sử dụng khóa

Hãy xem xét một kịch bản hoàn chỉnh: tạo khóa AES để mã hóa dữ liệu và tạo khóa EC để ký với bảo vệ sinh trắc học. Cả hai khóa đều được tạo bên trong Android KeyStore với hỗ trợ phần cứng.

Tạo khóa AES để mã hóa

Khóa AES được tạo thông qua KeyGenerator với KeyGenParameterSpec. Tham số: PURPOSE_ENCRYPT + PURPOSE_DECRYPT, BLOCK_MODE_GCM (chế độ được khuyến nghị với xác thực), ENCRYPTION_PADDING_NONE (không cần padding cho 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)
}

Ký với bảo vệ sinh trắc học

Khóa EC với userAuthenticationRequired=true yêu cầu xác thực người dùng trước mỗi thao tác ký. Để thực hiện điều này, BiometricPrompt với CryptoObject chứa đối tượng Signature được sử dụng. Sau khi xác minh sinh trắc học thành công, Keymaster cho phép thao tác.

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 và bảo mật thiết bị

Android KeyStore cung cấp các đảm bảo bảo mật ở cấp phần cứng mà KeyStore dựa trên phần mềm (JKS, BKS) không thể cung cấp. Các khóa được bảo vệ ở cấp SoC và ngay cả toàn quyền kiểm soát không gian người dùng Android cũng không cho phép trích xuất khóa riêng tư.

Key Attestation (Android 8.1+)

Key Attestation là cơ chế cho phép ứng dụng (và máy chủ) xác minh môi trường mà khóa được tạo ra. Android Keystore ký một chứng chỉ chứa danh sách các đặc tính của khóa: thuật toán, kích thước, mục đích, hỗ trợ phần cứng (True/False), nguồn gốc (GENERATED, IMPORTED). Máy chủ xác minh chuỗi chứng chỉ đến chứng chỉ gốc của Google.

Điều này rất quan trọng đối với các ứng dụng tài chính: máy chủ có thể yêu cầu khóa được tạo trong môi trường phần cứng (Hardware-Backed = True) và từ chối các khóa được tạo trong Keystore phần mềm. Key Attestation ngăn chặn các cuộc tấn công mà kẻ tấn công thay thế Keystore bằng trình giả lập.

Vô hiệu hóa khóa khi thay đổi sinh trắc học

setInvalidatedByBiometricEnrollment(true) có nghĩa là Keymaster sẽ tự động xóa khóa khi các mẫu sinh trắc học được thay đổi hoặc xóa. Điều này bảo vệ khỏi các cuộc tấn công mà kẻ tấn công thêm dấu vân tay của chúng vào tài khoản hiện có. Sau khi thêm dấu vân tay mới, các khóa cũ trở nên không thể truy cập.

Bộ đếm số lần xác thực sinh trắc học thất bại cũng được Keymaster quản lý. Sau maxBiometricAttempt (có thể cấu hình bởi nhà sản xuất, thường là 5), Keymaster chặn tất cả các thao tác với khóa sinh trắc học trong 30 giây. Sau 10 lần thất bại — cho đến khi nhập mật khẩu thiết bị (PIN bí mật).

Câu hỏi thường gặp

Sự khác biệt giữa Android KeyStore và Bouncy Castle KeyStore là gì?

Bouncy Castle (BKS) là KeyStore dựa trên phần mềm lưu trữ khóa trong tệp được bảo vệ bằng mật khẩu. Android KeyStore sử dụng cách ly phần cứng TEE/StrongBox. Khóa BKS có thể được trích xuất với quyền root, khóa Android KeyStore thì không. BKS phù hợp cho chứng chỉ CA, Android KeyStore phù hợp cho khóa riêng tư.

Có thể sử dụng một khóa cho cả mã hóa và ký không?

Có, nếu bạn chỉ định PURPOSE_ENCRYPT hoặc PURPOSE_DECRYPT hoặc PURPOSE_SIGN hoặc PURPOSE_VERIFY khi tạo. Tuy nhiên, phương pháp tốt nhất là tạo các khóa riêng biệt cho các thao tác khác nhau. Điều này giới hạn thiệt hại nếu một khóa bị xâm phạm và tuân theo nguyên tắc đặc quyền tối thiểu.

Làm thế nào để biết khóa có được hỗ trợ phần cứng trong Android KeyStore không?

Sử dụng KeyStore.getKeyCharacteristics(alias), có sẵn thông qua android.security.keystore. Phương thức trả về một tập hợp các cờ: FLAG_HARDWARE — khóa trong TEE, FLAG_SECURE_ELEMENT — khóa trong StrongBox. Nếu không có cờ nào, khóa chỉ là phần mềm.

Điều gì xảy ra khi tất cả các mẫu sinh trắc học bị xóa?

Tất cả các khóa được tạo với setInvalidatedByBiometricEnrollment(true) sẽ tự động bị Keymaster vô hiệu hóa. Khi cố gắng sử dụng, ứng dụng sẽ nhận được KeyPermanentlyInvalidatedException. Dữ liệu được mã hóa bằng các khóa này sẽ bị mất vĩnh viễn.

Android KeyStore có hỗ trợ sao lưu khóa không?

Khóa phần cứng (trong TEE/StrongBox) không hỗ trợ sao lưu — chúng được gắn với một thiết bị cụ thể. Khóa dựa trên phần mềm có thể được bao gồm trong bản sao lưu Google Drive. Để truyền dữ liệu giữa các thiết bị, hãy mã hóa dữ liệu trên máy chủ và giải mã trên thiết bị mới.

Tổng kết

  • Android KeyStore — nhà cung cấp JCA để lưu trữ khóa cách ly phần cứng qua Keymaster HAL trong TEE/StrongBox
  • KeyGenParameterSpec cấu hình thuật toán, kích thước, mục đích, digest, sinh trắc học và các giới hạn thời gian của khóa
  • RSA (KM 1.0+), EC (KM 1.0+), AES (KM 2.0+), ChaCha20 (KM 3.0+) — các thuật toán được hỗ trợ với các cấp Keymaster khác nhau
  • Key Attestation (API 28+) cho phép phía máy chủ xác minh nguồn gốc phần cứng của khóa
  • Bảo vệ khóa sinh trắc học qua setUserAuthenticationRequired + BiometricPrompt với CryptoObject
  • Vô hiệu hóa khóa khi thay đổi sinh trắc học ngăn chặn việc sử dụng trái phép dấu vân tay được thêm
  • Sử dụng Android KeyStore để tạo và lưu trữ khóa mật mã với bảo vệ phần cứng trong các ứng dụng Android

Chúng tôi sẽ phát triển ứng dụng di động chìa khóa trao tay

IT Sectr tạo các ứng dụng iOS và Android cho các công ty khởi nghiệp và doanh nghiệp từ năm 2017. Chúng tôi sẽ tư vấn và đề xuất giải pháp tốt nhất cho bạn.

Thảo luận dự án

Đọc thêm