Keystore (Android): คืออะไร สถาปัตยกรรมและหลักการทำงาน

ผู้แต่ง: IT Sectr เผยแพร่เมื่อ: 2026-03-14 เวลาอ่าน: 10 นาที

Android Keystore เป็นกลไกระบบใน Android สำหรับจัดเก็บคีย์เข้ารหัสอย่างปลอดภัยในการแยกฮาร์ดแวร์ ระบบใช้ Trusted Execution Environment (TEE) บนอุปกรณ์ที่มี ARM TrustZone หรือ Secure Element เฉพาะเพื่อปกป้องคีย์ในระดับชิป ตาม Android Open Source Project Keystore รองรับอัลกอริทึม RSA, EC, AES และ HMAC โดยสร้างคีย์โดยตรงในสภาพแวดล้อมที่ปลอดภัย

ประเด็นสำคัญ

  • Android Keystore เป็นผู้ให้บริการ KeyStore ที่แยกคีย์เข้ารหัสออกจากพื้นที่ผู้ใช้ Android
  • คีย์ ถูกสร้างขึ้นภายใน TEE หรือ Secure Element และไม่เคยออกจากสภาพแวดล้อมที่ปลอดภัยในรูปแบบข้อความธรรมดา
  • Android 9+ เพิ่ม KeyGenParameterSpec.Builder ด้วยพารามิเตอร์: purpose, digest, padding, userAuthenticationRequired
  • การป้องกันคีย์ด้วย biometric ต้องการการยืนยันผู้ใช้ผ่าน BiometricPrompt ก่อนการดำเนินการแต่ละครั้ง
  • Keymaster HAL เป็นชั้นนามธรรมฮาร์ดแวร์ที่ดำเนินการเข้ารหัสใน TEE หรือ Secure Element

Android Keystore คืออะไร?

Android Keystore เป็นผู้ให้บริการเข้ารหัสที่ถูกนำมาใช้ใน Android ตั้งแต่ API 1 (Android 1.0) แต่การรองรับฮาร์ดแวร์เต็มรูปแบบปรากฏใน Android 4.3 (API 18) Keystore แก้ปัญหาการจัดเก็บคีย์ส่วนตัวอย่างปลอดภัย เพื่อให้แม้ระบบปฏิบัติการถูกบุกรุก ผู้โจมตีก็ไม่สามารถดึงคีย์ในรูปแบบข้อความธรรมดาได้

สถาปัตยกรรม KeyStore บน Android

สถาปัตยกรรม Android Keystore ประกอบด้วยสามชั้น: API แอปพลิเคชัน (java.security.KeyStore), บริการระบบ (keystore daemon) และระดับฮาร์ดแวร์ (Keymaster HAL) แอปพลิเคชันเข้าถึงผ่าน API Java Cryptography Architecture (JCA) มาตรฐาน และบริการระบบจะส่งต่อคำขอไปยัง Keymaster ที่ทำงานใน TEE

การดำเนินการ เข้ารหัส ทั้งหมดกับคีย์ (การเซ็น การถอดรหัส) จะดำเนินการภายใน TEE หรือ Secure Element คีย์ไม่เคยออกจากสภาพแวดล้อมที่ปลอดภัย — แอปพลิเคชันได้รับเพียงแฮนเดิล (นามแฝง) เพื่ออ้างอิงถึงคีย์ นี่คือความแตกต่างพื้นฐานจาก KeyStore ซอฟต์แวร์ที่คีย์สามารถเข้าถึงได้ในหน่วยความจำกระบวนการ

ความแตกต่างจาก Java KeyStore

JKS (Java KeyStore) มาตรฐานหรือ BKS (Bouncy Castle) จัดเก็บคีย์ในไฟล์ที่ป้องกันด้วยรหัสผ่าน Android Keystore จัดเก็บคีย์ในการแยกฮาร์ดแวร์ ซึ่งได้รับการปกป้องแม้จากผู้ใช้รูท JKS เสี่ยงต่อการเข้าถึงระบบไฟล์โดยตรง ในขณะที่ Android Keystore ไม่เป็นเช่นนั้น

ความแตกต่างอีกประการ: ใน Android Keystore คีย์ มีพารามิเตอร์การใช้งานที่เข้มงวด (purpose — เฉพาะ sign/verify/encrypt/decrypt) ที่ระบุเวลาสร้าง ไม่สามารถเปลี่ยนแปลงได้ในภายหลัง ซึ่งป้องกันการใช้คีย์ในทางที่ผิด

Android Keystore ทำงานอย่างไร?

เมื่อสร้างคีย์ใหม่ แอปพลิเคชันเรียก KeyPairGenerator หรือ KeyGenerator ด้วย KeyGenParameterSpec ซึ่งมีพารามิเตอร์ทั้งหมดของคีย์ในอนาคต ระบบส่งคำขอไปยัง Keymaster HAL ซึ่งสร้างคีย์ภายใน TEE และส่งคืนแฮนเดิล

กระบวนการสร้างคีย์

เมธอด KeyGenParameterSpec.Builder ยอมรับพารามิเตอร์บังคับ: ชื่อคีย์ใน Keystore วัตถุประสงค์ (PURPOSE_SIGN, PURPOSE_ENCRYPT) อัลกอริทึม (RSA, EC, AES) เพิ่มเติม: digest (SHA-256), padding (PKCS7), userAuthenticationRequired (biometrics), keyValidityStart/End (ข้อจำกัดด้านเวลา)

หลังจากตั้งค่าพารามิเตอร์ KeyPairGenerator.generateKeyPair() ส่งคืน KeyPair โดย PrivateKey เป็นออบเจ็กต์ที่มอบหมายการดำเนินการให้ Keymaster คีย์สาธารณะสามารถดึงออกมาได้ แต่คีย์ส่วนตัวไม่สามารถทำได้ คีย์ส่วนตัวมีอยู่เฉพาะภายใน 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()
}

การเซ็นและการตรวจสอบ

Signature สำหรับ ECDSA หรือ RSA-PSS ถูกสร้างขึ้นผ่าน API มาตรฐาน: Signature.getInstance(algorithm).initSign(privateKey) การดำเนินการเซ็นจะดำเนินการใน TEE: แอปพลิเคชันส่งข้อมูล Keymaster เซ็นด้วยฮาร์ดแวร์และส่งคืนลายเซ็น คีย์และข้อมูลไม่ปะปนกันในหน่วยความจำที่ใช้ร่วมกัน

สำหรับการป้องกันด้วย biometric ผู้ใช้ต้องยืนยันตัวตนผ่าน BiometricPrompt ก่อนการเซ็น หากไม่มีการยืนยันตัวตนที่สำเร็จ Keymaster จะไม่ดำเนินการและส่งคืน 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 พร้อม CryptoObject(signature) ขอ FaceID/PIN
}

ประเภทพื้นที่จัดเก็บ KeyStore

Android รองรับสองโหมดการจัดเก็บคีย์: ซอฟต์แวร์ (บนอุปกรณ์ที่ไม่มี TEE) และ ฮาร์ดแวร์ (บนอุปกรณ์ที่มี TEE หรือ Secure Element) โหมดขึ้นอยู่กับความสามารถของ SoC และเวอร์ชัน Android

KeyStore ซอฟต์แวร์ (ซอฟต์แวร์เท่านั้น)

บนอุปกรณ์ที่ไม่มี Trusted Execution Environment (ก่อน Android 4.3 หรือ SoC ราคาประหยัด) คีย์จะถูกจัดเก็บแบบเข้ารหัสโดยใช้คีย์หลักที่ได้จากรหัสผ่านหน้าจอล็อก โหมดนี้ปลอดภัยน้อยกว่า — คีย์สามารถเข้าถึงได้ในหน่วยความจำกระบวนการระหว่างการดำเนินการเข้ารหัส

ระดับการป้องกันขึ้นอยู่กับการเข้ารหัส ไฟล์ KeyStore ด้วย AES-256-GCM คีย์เข้ารหัสถูกสร้างขึ้นจากรหัสผ่านหรือ PIN ของผู้ใช้ผ่าน Scrypt (PBKDF2 ด้วยจำนวนรอบสูง)

KeyMaster ฮาร์ดแวร์ (TEE/Secure Element)

บนอุปกรณ์สมัยใหม่ใช้ Keymaster 4.x ใน TEE (ARM TrustZone) คีย์ถูกสร้าง จัดเก็บ และใช้เฉพาะภายใน TrustZone เท่านั้น แม้แต่เคอร์เนล Linux ก็ไม่สามารถเข้าถึงคีย์ส่วนตัว — มีเพียง Keymaster HAL เท่านั้นที่สามารถดำเนินการได้

Secure Element (เช่น eSE ใน Samsung Knox หรือ StrongBox ใน Google Pixel 3+) เป็นชิปแยกต่างหากที่มีโปรเซสเซอร์และหน่วยความจำของตัวเอง ได้รับการรับรอง Common Criteria EAL 4+ และให้การป้องกันระดับสูงสุด รวมถึงการป้องกันการดัดแปลงทางกายภาพ

ประเภทตำแหน่งจัดเก็บระดับการป้องกันพร้อมใช้งานตั้งแต่ API
ซอฟต์แวร์ไฟล์ /data/misc/keystoreปานกลาง (AES-256)API 1+
Keymaster 3TEE (TrustZone)สูงAPI 23+
Keymaster 4TEE + Secure I/OสูงมากAPI 28+
StrongBoxSecure Element ฮาร์ดแวร์สูงสุดAPI 28+, ไม่บังคับ

การทำงานกับ KeyStore API

Android Keystore ถูกรวมเข้ากับ Java Cryptography Architecture (JCA) ในการเข้าถึงผู้ให้บริการ ใช้ KeyStore.getInstance("AndroidKeyStore") API พร้อมใช้งานตั้งแต่ API 18

การสร้างและโหลด KeyStore

เมธอด KeyStore.load(null) โหลดคอนเทนเนอร์ KeyStore ของแอปพลิเคชัน ไม่จำเป็นต้องใช้รหัสผ่าน — Android ใช้บริบทของแอปพลิเคชันและ UID ของมันในการควบคุมการเข้าถึง แต่ละแอปพลิเคชันเห็นเฉพาะรายการของตนเองเว้นแต่จะใช้ UID ที่ใช้ร่วมกัน

เมธอด setEntry และ getEntry ทำงานกับ KeyStore.PrivateKeyEntry, SecretKeyEntry หรือ TrustedCertificateEntry พารามิเตอร์ ProtectionParameter เป็น null เสมอสำหรับ Android Keystore (การป้องกันถูกนำไปใช้ในระดับระบบ)

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

การตรวจสอบประเภทพื้นที่จัดเก็บ

การใช้ KeyCharacteristics คุณสามารถระบุได้ว่าคีย์ถูกจัดเก็บในสภาพแวดล้อมใด: KeyStore ซอฟต์แวร์ TEE หรือ StrongBox เมธอด getKeyCharacteristics() ส่งคืนชุดของแฟล็ก: FLAG_HARDWARE (keymaster), FLAG_SECURE_ELEMENT (StrongBox), FLAG_TRUSTED_USER_PRESENCE_REQUIRED (biometrics)

อัลกอริทึมและความปลอดภัย

Android Keystore รองรับอัลกอริทึม เข้ารหัส หลากหลายแบ่งเป็นสามหมวด: อสมมาตร สมมาตร และ MAC การรองรับอัลกอริทึมเฉพาะขึ้นอยู่กับเวอร์ชันของ Keymaster HAL

อัลกอริทึมที่รองรับ

RSA (1024–4096 บิต) — สำหรับการเซ็น (PKCS1, PSS) และการเข้ารหัส (OAEP, PKCS1) EC (P-224, P-256, P-384, P-521) — สำหรับการเซ็น ECDHA และการตกลงคีย์ ECDH AES (128, 256 บิต) — สำหรับการเข้ารหัสสมมาตรในโหมด CBC, CTR, GCM HMAC (SHA1, SHA256, SHA512) — สำหรับการยืนยันตัวตนข้อความ

สำหรับแต่ละ คีย์ setPurposes จะถูกระบุเพื่อจำกัดการดำเนินการที่เป็นไปได้ คีย์ RSA ที่มี PURPOSE_SIGN ไม่สามารถใช้สำหรับการเข้ารหัสได้ แม้ผู้โจมตีจะมีการเข้าถึง API นี่คือการบังคับใช้คีย์ในระดับฮาร์ดแวร์

การป้องกันจากการบุกรุก

Keymaster มีตัวนับความพยายามยืนยันตัวตนแบบ biometric ที่ล้มเหลว หลังจากจำนวนความล้มเหลวที่กำหนด (กำหนดค่าได้ผ่าน setInvalidatedByBiometricEnrollment) คีย์จะไม่สามารถใช้งานได้และต้องลบ/สร้างใหม่ เมื่อแม่แบบ biometric ทั้งหมดถูกลบ คีย์ทั้งหมดที่มี userAuthenticationRequired=true จะถูกทำให้ไม่ถูกต้องโดยอัตโนมัติ

Key Attestation (Android 8.1+) ก็รองรับเช่นกัน: ตามคำขอของแอปพลิเคชัน Keymaster เซ็นใบรับรองพร้อมข้อมูลเกี่ยวกับคุณลักษณะของคีย์ (ฮาร์ดแวร์/ซอฟต์แวร์ อัลกอริทึม วัตถุประสงค์) เซิร์ฟเวอร์สามารถตรวจสอบใบรับรองนี้เพื่อยืนยันว่าคีย์ถูกสร้างขึ้นในสภาพแวดล้อมที่เชื่อถือได้

คำถามที่พบบ่อย

ความแตกต่างระหว่าง Android Keystore และ Java KeyStore คืออะไร?

Java KeyStore จัดเก็บคีย์ในไฟล์ที่ป้องกันด้วยรหัสผ่าน (JKS, BKS) Android Keystore ใช้การแยกฮาร์ดแวร์ผ่าน TEE หรือ Secure Element Java KeyStore เสี่ยงต่อการเข้าถึงรูท ในขณะที่ Android Keystore ไม่เป็นเช่นนั้น เพราะคีย์ส่วนตัวไม่เคยออกจากสภาพแวดล้อมที่ปลอดภัย

ฉันสามารถนำเข้าคีย์ที่มีอยู่ใน Android Keystore ได้หรือไม่?

ได้ ผ่าน KeyStore.setEntry ด้วย KeyProtection อย่างไรก็ตาม คีย์ที่นำเข้าจะไม่มีการป้องกันฮาร์ดแวร์ — คีย์จะถูกจัดเก็บใน Keystore ซอฟต์แวร์ เข้ารหัสด้วยคีย์หลัก เพื่อความปลอดภัยสูงสุด ให้สร้างคีย์ภายใน Keystore เสมอ

จะตรวจสอบว่าอุปกรณ์รองรับ KeyStore ฮาร์ดแวร์ได้อย่างไร?

ใช้ KeyChain.isBoundKeyAlgorithm หรือตรวจสอบ KeyCharacteristics หลังสร้างคีย์ การมี FLAG_HARDWARE ในคุณลักษณะหมายความว่าคีย์ถูกสร้างใน TEE คุณยังสามารถตรวจสอบ android.security.keystore.isHardwareBacked()

เกิดอะไรขึ้นกับคีย์เมื่อถอนการติดตั้งแอปพลิเคชัน?

เมื่อ ถอนการติดตั้ง แอปพลิเคชัน Android จะลบคีย์ทั้งหมดออกจาก Keystore ข้อมูลจะสูญหายอย่างถาวร เมื่อติดตั้งใหม่ แอปพลิเคชันต้องสร้างคีย์ใหม่ การสำรองคีย์ผ่าน TEE เป็นไปไม่ได้ด้วยเหตุผลทางสถาปัตยกรรม

KeyStore ป้องกันการโจมตีจากการดีบักอย่างไร?

บนอุปกรณ์ที่ ล็อก Keymaster ไม่ดำเนินการใดๆ คีย์ที่มี userAuthenticationRequired=true ต้องการการยืนยัน biometric ทุกครั้ง แม้มีการเข้าถึงรูท ผู้โจมตีไม่สามารถเรียก Keymaster โดยตรง — ผ่านบริการ Android Keystore เท่านั้น

สรุป

  • Android Keystore เป็นผู้ให้บริการเข้ารหัส JCA พร้อมการแยกคีย์ฮาร์ดแวร์ผ่าน TEE หรือ Secure Element
  • คีย์ ถูกสร้างขึ้นภายใน TrustZone และไม่เคยออกจากสภาพแวดล้อมที่ปลอดภัยในรูปแบบข้อความธรรมดา
  • KeyGenParameterSpec กำหนดพารามิเตอร์คีย์: purpose, digest, padding, userAuthenticationRequired, keyValidity
  • Keymaster HAL นำเสนอสามระดับ: ซอฟต์แวร์, TEE (Keymaster 3/4) และ StrongBox (Secure Element ฮาร์ดแวร์)
  • การป้องกันคีย์ด้วย biometric มีให้ผ่าน setUserAuthenticationRequired และ BiometricPrompt พร้อม CryptoObject
  • Key Attestation (API 28+) ช่วยให้ตรวจสอบฝั่งเซิร์ฟเวอร์ว่าคีย์ถูกสร้างในสภาพแวดล้อมฮาร์ดแวร์
  • ใช้ Android Keystore เพื่อจัดเก็บคีย์ส่วนตัวสำหรับการเซ็น การเข้ารหัส และการยืนยันตัวตนในแอปพลิเคชัน Android

เราจะพัฒนาแอปพลิเคชันบนมือถือแบบครบวงจร

IT Sectr สร้างแอปพลิเคชัน iOS และ Android สำหรับสตาร์ทอัพและธุรกิจตั้งแต่ปี 2017 เราจะให้คำแนะนำและเสนอวิธีแก้ปัญหาที่ดีที่สุดแก่คุณ

ปรึกษาโครงการ

อ่านเพิ่มเติม