Android Keystore — nhà cung cấp mật mã tạo và lưu trữ khóa mã hóa trong môi trường thực thi biệt lập (TEE), không thể truy cập ngay cả đối với hệ điều hành. Theo AOSP Security Documentation (2025), hơn 80% ứng dụng Android trong top 100 Google Play sử dụng Keystore để bảo vệ token và mã hóa dữ liệu. Hiểu Android Keystore là rất quan trọng để lưu trữ khóa an toàn trên Android.
Chính yếu
Android Keystore — thành phần hệ thống của nền tảng Android cung cấp API để tạo, lưu trữ và sử dụng khóa mật mã trong môi trường bảo vệ. Không giống như các thư viện mật mã phần mềm (Bouncy Castle, Conscrypt), Keystore đảm bảo khóa riêng tư không bao giờ rời khỏi vùng thực thi biệt lập.
Keystore xuất hiện trong Android 4.3 (API 18) như một nhà cung cấp phần mềm hỗ trợ RSA. Bắt đầu từ Android 6.0 (API 23), Keystore nhận được hỗ trợ phần cứng thông qua Keymaster Hardware Abstraction Layer (HAL), ủy quyền các thao tác mật mã cho Trusted Execution Environment (TEE) trên các thiết bị tương thích. Theo Android Compatibility Definition Document (2025), tất cả thiết bị Android 9+ phải hỗ trợ Keystore phần cứng qua TEE hoặc StrongBox.
Khóa trong Keystore được xác định bằng bí danh (alias) — một chuỗi được truyền khi tạo hoặc tải khóa. Keystore không cho phép lấy nguyên liệu thô của khóa: phương thức getEncoded() trả về null cho các khóa được tạo trong Keystore. Đây là sự khác biệt cơ bản so với khóa phần mềm — kẻ tấn công không thể trích xuất khóa riêng tư ngay cả khi kiểm soát hoàn toàn thiết bị.
Keystore được tích hợp với các cơ chế bảo mật khác của Android: xác thực sinh trắc học (BiometricPrompt), mã hóa cấp tệp (File-Based Encryption) và chức năng xác minh SafetyNet/Play Integrity. Khóa có thể được cấu hình để tự động xóa trong các điều kiện nhất định: khi xóa mật mã, khi thêm vân tay mới hoặc khi hết hạn.
Kiến trúc của Android Keystore bao gồm ba cấp độ triển khai khác nhau về mức độ bảo vệ phần cứng. Cấp độ phụ thuộc vào khả năng phần cứng của thiết bị.
TEE (Trusted Execution Environment) — vùng biệt lập hoạt động song song với hệ điều hành chính trên cùng bộ xử lý. TEE sử dụng công nghệ ARM TrustZone, chia nhân vật lý của bộ xử lý thành hai vùng ảo: Normal World (Android) và Secure World (TEE). Mã trong Secure World có quyền truy cập vào bộ nhớ và thiết bị ngoại vi mà Normal World không thể truy cập.
Khi ứng dụng gọi thao tác mật mã qua Keystore, yêu cầu được gửi qua Keymaster HAL đến TEE, nơi thao tác được thực thi bằng phần cứng. Kết quả được trả về ứng dụng nhưng khóa riêng tư vẫn ở trong bộ nhớ được bảo vệ của TEE. TEE được chứng nhận tuân thủ GlobalPlatform TEE Protection Profile và là yêu cầu bắt buộc đối với thiết bị Android 9+ có bộ xử lý hỗ trợ TrustZone.
TEE hỗ trợ các thuật toán AES/GCM (128, 256 bit), RSA (2048, 4096 bit), EC (P-256, P-384, P-521) và HMAC-SHA256. Hiệu suất của TEE thấp hơn mật mã phần mềm (thấp hơn 20–40%), nhưng đối với các thao tác điển hình (ký JWT, giải mã khóa phiên), độ trễ không vượt quá 10–50 ms.
StrongBox — chip bảo mật chuyên dụng, tách biệt vật lý khỏi bộ xử lý chính. Không giống TEE chia sẻ thời gian xử lý với Android, StrongBox có CPU riêng, RAM, True Random Number Generator (TRNG) và bộ nhớ được bảo vệ (One-Time Programmable memory). StrongBox được chứng nhận Common Criteria EAL 4+ và Secure IC Protection Profile.
StrongBox khả dụng trên thiết bị Android 9+ khi có chip tương ứng (ví dụ: Titan M trên Google Pixel, Knox trên Samsung Galaxy). Nhà phát triển kích hoạt StrongBox qua cờ setIsStrongBoxBacked(true) trong KeyGenParameterSpec. Khi không có hỗ trợ phần cứng, cờ bị bỏ qua và Keystore chuyển sang TEE.
Hạn chế của StrongBox: hỗ trợ tập thuật toán giới hạn (AES-256, EC P-256, HMAC-SHA256), hàng đợi thao tác — tối đa một lần, số lượng thao tác — giới hạn bởi tài nguyên chip. StrongBox không dành cho kịch bản tải cao — sử dụng TEE cho các thao tác thường xuyên và StrongBox chỉ cho khóa quan trọng (khóa mã hóa chính, khóa ký).
Keystore dựa trên phần mềm — triển khai phần mềm sử dụng trên thiết bị không có hỗ trợ phần cứng TEE hoặc StrongBox. Khóa được lưu dưới dạng mã hóa trong hệ thống tệp, nhưng khóa riêng tư có thể được giải mã tạm thời trong RAM. Keystore phần mềm kém an toàn hơn — kẻ tấn công có quyền root có thể chặn khóa trong bộ nhớ.
Bắt đầu từ Android 12 (API 31), Google yêu cầu hỗ trợ Keystore phần cứng cho tất cả thiết bị mới. Thiết bị Android 9–11 có thể có Keystore phần mềm trên các mẫu giá rẻ. Nhà phát triển có thể kiểm tra mức bảo vệ qua KeyStore.getKeyCharacteristics() — thuộc tính SECURITY_LEVEL_TRUSTED_ENVIRONMENT hoặc SECURITY_LEVEL_STRONGBOX xác nhận bảo vệ phần cứng.
Android Keystore hỗ trợ nhiều thuật toán mật mã, được phân loại theo loại khóa. Lựa chọn thuật toán ảnh hưởng đến hiệu suất, tương thích và mức bảo mật.
AES (Advanced Encryption Standard) — mã hóa đối xứng để bảo vệ dữ liệu trên thiết bị. Chế độ khuyến nghị: AES/GCM/NoPadding (256 bit). GCM cung cấp mã hóa xác thực (AEAD) — kiểm tra tính toàn vẹn của dữ liệu đã mã hóa. Kích thước IV (Initialization Vector) cho GCM: 12 byte. Không sử dụng AES/ECB — nó không cung cấp bảo vệ thích hợp.
RSA (Rivest–Shamir–Adleman) — mã hóa bất đối xứng để bảo vệ khóa phiên và chữ ký số. Kích thước khuyến nghị: 2048 hoặc 4096 bit. Chế độ: RSA/ECB/PKCS1Padding (mã hóa) và RSA/ECB/PKCS1Sign (ký). RSA 1024 được coi là lỗi thời và không được khuyến nghị cho ứng dụng mới (NIST SP 800-131A Rev. 2).
EC (Elliptic Curve) — mật mã đường cong elliptic bất đối xứng cho ký và trao đổi khóa. Đường cong hỗ trợ: secp256r1 (P-256, bắt buộc), secp384r1 (P-384) và secp521r1 (P-521). EC cung cấp bảo mật tương đương RSA với kích thước khóa nhỏ hơn đáng kể. P-256 được khuyến nghị cho hầu hết kịch bản: được tất cả thiết bị hỗ trợ và cung cấp mức bảo mật 128-bit.
HMAC (Hash-based Message Authentication Code) — xác thực đối xứng thông điệp. Hàm băm hỗ trợ: SHA-256, SHA-384, SHA-512. HMAC được sử dụng để kiểm tra tính toàn vẹn và xác thực dữ liệu, ví dụ, xác minh yêu cầu webhook hoặc kiểm tra tính toàn vẹn cấu hình.
Tất cả thuật toán có thể được ràng buộc với xác thực sinh trắc học qua KeyGenParameterSpec.Builder.setUserAuthenticationRequired(true). Trên Android 11+, cờ setUserAuthenticationParameters() khả dụng để chỉ định thời gian chờ (tính bằng giây) trong đó khóa khả dụng sau xác thực sinh trắc học mà không cần yêu cầu lại.
Xem các ví dụ thực tế với Android Keystore trên Kotlin: tạo khóa AES, mã hóa dữ liệu và tạo cặp bất đối xứng để ký.
Ví dụ tạo khóa AES/GCM 256-bit với ràng buộc xác thực sinh trắc học. Khóa không thể xuất qua 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()
}
Ví dụ mã hóa dữ liệu bằng khóa từ Android Keystore. Cipher lấy khóa theo bí danh, khởi tạo mã hóa AES/GCM và trả về dữ liệu đã mã hóa cùng với 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 + dữ liệu đã mã hóa
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)
}
Ví dụ tạo cặp khóa RSA-2048 trong Keystore với ràng buộc StrongBox. Khóa riêng tư được dùng để ký, khóa công khai có thể được xuất qua 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()
// Khóa công khai có thể được xuất
val publicKey = pair.public // X509EncodedKeySpec
}
Sử dụng hiệu quả Android Keystore đòi hỏi tuân thủ các quy tắc đảm bảo bảo vệ tối đa trong khi duy trì hiệu suất.
Sử dụng KeyGenParameterSpec với tham số tối thiểu cần thiết: chỉ chỉ định những purpose, block modes và paddings thực sự được sử dụng. Tham số dư thừa (ví dụ: PURPOSE_ENCRYPT cho khóa chỉ dùng để ký) tạo ra các vector tấn công không cần thiết. Android khuyến nghị chỉ định rõ ràng digest cho ký — SHA256 là mức tối thiểu chấp nhận được (SHA1 đã lỗi thời).
Ràng buộc khóa với sinh trắc học cho các thao tác quan trọng: setUserAuthenticationRequired(true) đảm bảo khóa chỉ có thể được sử dụng sau xác thực sinh trắc học. Trên Android 11+, sử dụng setUserAuthenticationParameters() với thời gian chờ (khuyến nghị 30–60 giây) để không yêu cầu sinh trắc học cho mỗi thao tác trong cùng phiên. setInvalidatedByBiometricEnrollment(true) tự động xóa khóa khi thêm vân tay hoặc khuôn mặt mới — ngăn truy cập qua dữ liệu sinh trắc học cũ.
Kiểm tra mức bảo mật ở giai đoạn khởi tạo: sử dụng KeyStore.getKeyCharacteristics() để xác định SECURITY_LEVEL. Nếu thiết bị chỉ hỗ trợ Keystore phần mềm (SECURITY_LEVEL_SOFTWARE), hãy quyết định: từ chối chức năng hoặc sử dụng mã hóa bổ sung (ví dụ: bọc khóa qua mật khẩu người dùng). Không phụ thuộc vào StrongBox nếu nó không được đảm bảo — luôn chỉ định cờ setIsStrongBoxBacked(true) và kiểm tra kết quả qua getKeyCharacteristics.
Cập nhật khóa theo lịch trình: khóa mật mã có vòng đời khuyến nghị. NIST SP 800-57 khuyến nghị thay đổi khóa AES mỗi 1–2 năm, cặp RSA/EC mỗi 2–3 năm. Triển khai cơ chế luân chuyển khóa: khi khởi động ứng dụng, kiểm tra ngày tạo khóa (KeyGenParameterSpec.Builder.setKeyValidityStart/End) và tạo khóa mới khi hết hạn. Dữ liệu cũ đã mã hóa bằng khóa cũ phải được giải mã và mã hóa lại bằng khóa mới.
Không sử dụng Keystore cho dữ liệu lớn: Keystore dành cho lưu trữ khóa (vài trăm byte), không phải để mã hóa tệp lớn. Để mã hóa dữ liệu, sử dụng sơ đồ: tạo khóa AES ngẫu nhiên (DEK — Data Encryption Key), mã hóa dữ liệu bằng khóa này, và mã hóa DEK bằng khóa Keystore (KEK — Key Encryption Key). Android EncryptedSharedPreferences sử dụng chính sơ đồ này: khóa chính trong Keystore, dữ liệu — AES-256 GCM.
Câu hỏi thường gặp
Không, Android Keystore được thiết kế để khóa riêng tư không bao giờ rời khỏi TEE hoặc StrongBox. Phương thức getEncoded() trả về null cho khóa được tạo trong Keystore. Khóa chỉ có thể được sử dụng qua Cipher, Signature hoặc Mac API — nguyên liệu thô không khả dụng.
TEE (TrustZone) — cô lập ảo trên cùng bộ xử lý, sử dụng phân chia thời gian. StrongBox — chip riêng với CPU và bộ nhớ riêng. StrongBox an toàn hơn (Common Criteria EAL 4+), nhưng chậm hơn và hỗ trợ ít thuật toán hơn. TEE phù hợp cho thao tác thường xuyên, StrongBox — cho khóa quan trọng.
Sử dụng KeyStore.getKeyCharacteristics() sau khi tạo khóa với cờ setIsStrongBoxBacked(true). Thuộc tính SECURITY_LEVEL_STRONGBOX xác nhận hỗ trợ phần cứng. Nếu thiết bị không hỗ trợ StrongBox, Keystore chuyển sang TEE mà không báo lỗi — cần kiểm tra tường minh mức bảo mật.
Khóa trong Keystore tự động bị xóa khi xóa ứng dụng khỏi thiết bị. Trên Android 10+, khóa có thể được giữ lại nếu ứng dụng có cờ allowBackup=true trong tệp kê khai, nhưng sẽ không khả dụng sau khi cài đặt lại. Khuyến nghị tạo lại khóa khi cài đặt sạch.
Không, Android Keystore được ràng buộc với phần cứng của thiết bị cụ thể. Khóa được tạo trong TEE của một thiết bị không thể chuyển sang thiết bị khác. Để mã hóa đa nền tảng, sử dụng sơ đồ: Keystore bảo vệ khóa trên thiết bị, và khóa phiên được truyền qua API bảo mật sử dụng mã hóa bất đối xứng.
Tổng kết
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.
Đọc thêm