KeyStore (Android): แนวคิดหลัก API และการทำงานของพื้นที่จัดเก็บการเข้ารหัส

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

KeyStore (Android) คือการใช้งานผู้ให้บริการเข้ารหัส Java Cryptography Architecture (JCA) ที่รวมอยู่ใน Android เพื่อการจัดเก็บคีย์อย่างปลอดภัยด้วยความสามารถในการแยกฮาร์ดแวร์ ตั้งแต่ Android 4.3 (API 18) KeyStore รองรับคีย์ฮาร์ดแวร์ผ่าน Keymaster HAL และตั้งแต่ Android 9 (API 28) รองรับ StrongBox Keymaster สำหรับคีย์ใน Secure Element โดยเฉพาะ ตาม เอกสารความปลอดภัยของ Android ผู้ให้บริการ “AndroidKeyStore” แทนที่ Bouncy Castle หรือ OpenSSL KeyStore มาตรฐาน โดยให้การป้องกันระดับระบบต่อการดึงคีย์โดยไม่ได้รับอนุญาต

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

  • Android KeyStore คือผู้ให้บริการ JCA สำหรับจัดเก็บคีย์ด้วยการรองรับ TEE, StrongBox และการป้องกันไบโอเมตริก
  • KeyGenParameterSpec กำหนดอัลกอริทึม วัตถุประสงค์ digest padding และไบโอเมตริกเมื่อสร้างคีย์
  • Keymaster HAL ดำเนินการเข้ารหัสฮาร์ดแวร์ในระดับ Software, TEE และ StrongBox
  • Key Attestation (API 28+) ช่วยให้เซิร์ฟเวอร์ตรวจสอบว่าคีย์ถูกสร้างขึ้นในสภาพแวดล้อมฮาร์ดแวร์ของ Android KeyStore
  • นามแฝงของคีย์คือสตริงที่แอปพลิเคชันใช้เข้าถึงคีย์ใน Keystore; หนึ่งนามแฝงสอดคล้องกับหนึ่งคีย์

KeyStore ใน Android คืออะไร?

KeyStore ใน Android ไม่ใช่แอปพลิเคชันหรือไฟล์แยกต่างหาก แต่เป็นผู้ให้บริการเข้ารหัสที่ใช้อินเทอร์เฟส java.security.KeyStore โดยให้ API แบบรวมสำหรับจัดเก็บและใช้คีย์ส่วนตัว คีย์สมมาตร และใบรับรอง CA ที่เชื่อถือได้ ผู้ให้บริการลงทะเบียนภายใต้ชื่อ “AndroidKeyStore” และสามารถเข้าถึงได้ผ่าน KeyStore.getInstance() มาตรฐาน

วิวัฒนาการของ Android KeyStore

ก่อน Android 4.3 การดำเนินการ เข้ารหัส ดำเนินการผ่าน Bouncy Castle Android 4.3 เปิดตัว Keymaster HAL 1.0 ทำให้สามารถใช้ TEE บน ARM TrustZone ได้ Android 6.0 (API 23) เพิ่ม Keymaster 2.0 พร้อมการยืนยันตัวตนด้วยลายนิ้วมือบนฮาร์ดแวร์ Android 9 (API 28) เปิดตัว Keymaster 4.0 และ StrongBox Keymaster สำหรับ Secure Element โดยเฉพาะ

แต่ละ เวอร์ชัน ของ Keymaster เพิ่มความสามารถใหม่และปรับปรุงการแยกคีย์ อุปกรณ์สมัยใหม่ (2022+) ต้องรองรับ Keymaster 4.0 สำหรับการรับรอง Google Mobile Services ซึ่งรับประกันความพร้อมใช้งานของ TEE สำหรับแอปพลิเคชัน Android ทั้งหมด

สถาปัตยกรรมและส่วนประกอบ

Android KeyStore ประกอบด้วยสาม ชั้น: Java API (KeyStore, KeyPairGenerator), กระบวนการระบบ keystore (C++, ทำงานเป็นบริการระบบ) และ Keymaster HAL (ไลบรารีใน TEE หรือ Secure Element) แอปพลิเคชันเรียก API บริการ keystore ส่งคำขอไปยัง Keymaster และการดำเนินการถูกดำเนินการในสภาพแวดล้อมที่ปลอดภัย

คีย์ ส่วนตัว ทั้งหมดถูกเก็บไว้ใน TEE และไม่สามารถอ่านได้จากพื้นที่ผู้ใช้ แม้แต่บริการ keystore ของระบบก็ไม่สามารถเข้าถึงคีย์ดิบได้ — เฉพาะแฮนเดิลที่ชี้ไปยังคีย์ภายใน Keymaster

KeyStore ทำงานเป็นผู้ให้บริการเข้ารหัสอย่างไร?

Android KeyStore ใช้อินเทอร์เฟสผู้ให้บริการ JCA มาตรฐาน เมื่อแอปพลิเคชันเรียก Cipher.getInstance(“RSA/ECB/PKCS1Padding”, “AndroidKeyStore”) ผู้ให้บริการความปลอดภัย Android มอบหมายการดำเนินการให้ Keymaster ผ่าน chain: Java → JNI → บริการ keystore → Keymaster HAL

การลงทะเบียนผู้ให้บริการ

ผู้ให้บริการ AndroidKeyStore ลงทะเบียนโดยอัตโนมัติเมื่อเริ่มกระบวนการ ลำดับความสำคัญสูงกว่า Bouncy Castle หรือ Conscrypt ดังนั้นเมื่อเรียก KeyStore.getInstance() โดยไม่ระบุผู้ให้บริการ ในกรณีส่วนใหญ่จะส่งคืน AndroidKeyStore สำหรับการเรียกอย่างชัดเจน ให้ใช้ KeyStore.getInstance(“AndroidKeyStore”)

แต่ละแอปพลิเคชัน Android มีคอนเทนเนอร์ที่ แยก ใน KeyStore แอปพลิเคชันที่มี UID เดียวกัน (shared userId) สามารถแชร์การเข้าถึงคีย์บางอย่างได้ แต่การตั้งค่ามาตรฐานรับประกันว่าแอปพลิเคชัน A ไม่สามารถอ่านคีย์ของแอปพลิเคชัน B

เมธอดของ KeyStore และลักษณะเฉพาะ

load(null) — การเริ่มต้น KeyStore พารามิเตอร์เป็น null เสมอสำหรับ AndroidKeyStore setEntry — บันทึกคีย์ด้วย KeyProtection ที่ระบุ (วัตถุประสงค์, digest, padding) getEntry — ดึง KeyStore.PrivateKeyEntry, SecretKeyEntry หรือ TrustedCertificateEntry containsAlias — ตรวจสอบว่าคีย์มีอยู่หรือไม่ deleteEntry — ลบคีย์อย่างถาวร

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

อัลกอริทึมและประเภทคีย์ที่รองรับ

Android KeyStore รองรับชุดอัลกอริทึมการเข้ารหัสที่ หลากหลาย ซึ่งแตกต่างกันไปตามเวอร์ชัน Keymaster HAL บนอุปกรณ์ นักพัฒนาสามารถรับรายการอัลกอริทึมที่รองรับผ่าน KeyGenParameterSpec.Builder เมื่อพยายามสร้าง — พารามิเตอร์ที่เข้ากันไม่ได้จะโยน InvalidAlgorithmParameterException

อัลกอริทึมแบบอสมมาตร

RSA (1024–4096 บิต) — สำหรับลายเซ็น (PKCS1, PSS กับ SHA-1/SHA-256/SHA-384/SHA-512) และการเข้ารหัส (OAEP กับ SHA-1/SHA-256) EC (P-224, P-256, P-384, P-521) — สำหรับลายเซ็น ECDSA และการตกลงคีย์ ECDH X25519 และ Ed25519 — ตั้งแต่ Android 12 (API 31) สำหรับโปรโตคอลการเข้ารหัสสมัยใหม่

สำหรับคีย์ อสมมาตร ให้สร้างภายใน Keymaster เสมอ อย่านำเข้าคีย์ส่วนตัว คีย์ส่วนตัวที่นำเข้าไม่ได้รับการป้องกันด้วยฮาร์ดแวร์ — ถูกเก็บในชั้นซอฟต์แวร์และเสี่ยงต่อการถูกโจมตีหากกระบวนการของแอปพลิเคชันถูกบุกรุก

อัลกอริทึมแบบสมมาตร

AES (128, 256 บิต) — สำหรับการเข้ารหัสแบบสมมาตรในโหมด CBC, CTR, GCM HMAC (SHA-1, SHA-256, SHA-512) — สำหรับการยืนยันตัวตนข้อความ ChaCha20 (Android 12+) — สำหรับการเข้ารหัสสตรีมประสิทธิภาพสูงด้วยการยืนยันตัวตน Poly1305

อัลกอริทึมKeymasterวัตถุประสงค์API
RSAKM 1.0+ลายเซ็น, การเข้ารหัส18+
ECKM 1.0+ECDSA, ECDH18+
AESKM 2.0+การเข้ารหัสแบบสมมาตร23+
HMACKM 2.0+รหัสยืนยันตัวตน23+
ChaCha20KM 3.0+การเข้ารหัสสตรีม31+
X25519/Ed25519KM 3.0+การแลกเปลี่ยนคีย์31+

ประเภทคีย์และการทำให้เป็นอนุกรม

KeyStore.PrivateKeyEntry — ประกอบด้วยคีย์ส่วนตัว (ไม่สามารถส่งออกได้) และห่วงโซ่ใบรับรอง KeyStore.SecretKeyEntry — สำหรับคีย์สมมาตร KeyStore.TrustedCertificateEntry — สำหรับใบรับรอง CA ที่เชื่อถือได้ คีย์สาธารณะสามารถส่งออกได้ผ่าน keyStore.getCertificate(alias).publicKey

ตัวอย่างการสร้างและการใช้คีย์

มาดู สถานการณ์ที่สมบูรณ์: การสร้างคีย์ AES สำหรับการเข้ารหัสข้อมูลและการสร้างคีย์ EC สำหรับลายเซ็นด้วยการป้องกันไบโอเมตริก คีย์ทั้งสองถูกสร้างขึ้นภายใน Android KeyStore ด้วยการรองรับฮาร์ดแวร์

การสร้างคีย์ AES สำหรับการเข้ารหัส

คีย์ AES ถูกสร้างผ่าน KeyGenerator ด้วย KeyGenParameterSpec พารามิเตอร์: PURPOSE_ENCRYPT + PURPOSE_DECRYPT, BLOCK_MODE_GCM (โหมดแนะนำพร้อมการยืนยันตัวตน), ENCRYPTION_PADDING_NONE (ไม่จำเป็นต้องใช้ padding สำหรับ 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)
}

ลายเซ็นด้วยการป้องกันไบโอเมตริก

คีย์ EC ที่มี userAuthenticationRequired=true ต้องการการยืนยันตัวตนผู้ใช้ก่อนการดำเนินการลายเซ็นแต่ละครั้ง โดยใช้ BiometricPrompt กับ CryptoObject ที่มีออบเจกต์ Signature หลังจากการตรวจสอบไบโอเมตริกสำเร็จ Keymaster อนุญาตให้ดำเนินการ

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 และความปลอดภัยของอุปกรณ์

Android KeyStore ให้ การรับประกัน ความปลอดภัยระดับฮาร์ดแวร์ที่ KeyStore บนซอฟต์แวร์ (JKS, BKS) ไม่สามารถให้ได้ คีย์ได้รับการป้องกันในระดับ SoC และแม้แต่การควบคุมพื้นที่ผู้ใช้ Android อย่างสมบูรณ์ก็ไม่อนุญาตให้ดึงคีย์ส่วนตัวออกมา

Key Attestation (Android 8.1+)

Key Attestation เป็นกลไกที่ช่วยให้แอปพลิเคชัน (และเซิร์ฟเวอร์) ตรวจสอบสภาพแวดล้อมที่สร้างคีย์ Android Keystore ลงนามใบรับรองที่มีรายการคุณลักษณะของคีย์: อัลกอริทึม, ขนาด, วัตถุประสงค์, รองรับฮาร์ดแวร์ (True/False), แหล่งกำเนิด (GENERATED, IMPORTED) เซิร์ฟเวอร์ตรวจสอบห่วงโซ่ใบรับรองจนถึงใบรับรองรากของ Google

นี่เป็นสิ่งสำคัญสำหรับแอปพลิเคชัน ทางการเงิน: เซิร์ฟเวอร์สามารถกำหนดให้คีย์ถูกสร้างในสภาพแวดล้อมฮาร์ดแวร์ (Hardware-Backed = True) และปฏิเสธคีย์ที่สร้างใน Keystore ซอฟต์แวร์ Key Attestation ป้องกันการโจมตีที่ผู้โจมตีแทนที่ Keystore ด้วยอีมูเลเตอร์

การทำให้คีย์ไม่ถูกต้องเมื่อเปลี่ยนไบโอเมตริก

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

ตัวนับความพยายามยืนยันตัวตนไบโอเมตริกที่ ล้มเหลว ก็ถูกจัดการโดย Keymaster หลังจาก maxBiometricAttempt (กำหนดค่าโดยผู้ผลิต โดยปกติคือ 5) Keymaster บล็อกการดำเนินการทั้งหมดด้วยคีย์ไบโอเมตริกเป็นเวลา 30 วินาที หลังจาก 10 ครั้งที่ล้มเหลว — จนกว่าจะป้อนรหัสผ่านอุปกรณ์ (PIN ลับ)

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

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

Bouncy Castle (BKS) คือ KeyStore บนซอฟต์แวร์ที่เก็บคีย์ในไฟล์ที่ป้องกันด้วยรหัสผ่าน Android KeyStore ใช้การแยกฮาร์ดแวร์ TEE/StrongBox คีย์ BKS สามารถดึงออกได้ด้วยการเข้าถึง root คีย์ Android KeyStore ไม่สามารถ BKS เหมาะสำหรับใบรับรอง CA, Android KeyStore สำหรับคีย์ส่วนตัว

สามารถใช้คีย์เดียวกันสำหรับการเข้ารหัสและลายเซ็นได้หรือไม่?

ได้ หากคุณระบุ PURPOSE_ENCRYPT หรือ PURPOSE_DECRYPT หรือ PURPOSE_SIGN หรือ PURPOSE_VERIFY ขณะ สร้าง อย่างไรก็ตาม แนวทางปฏิบัติที่ดีที่สุดคือสร้างคีย์แยกต่างหากสำหรับการดำเนินการที่แตกต่างกัน ซึ่งจำกัดความเสียหายหากคีย์หนึ่งถูกบุกรุกและเป็นไปตามหลักการสิทธิพิเศษน้อยที่สุด

จะทราบได้อย่างไรว่าคีย์รองรับฮาร์ดแวร์ใน Android KeyStore หรือไม่?

ใช้ KeyStore.getKeyCharacteristics(alias) ที่มีให้ผ่าน android.security.keystore เมธอดส่งคืนชุดของ flags: FLAG_HARDWARE — คีย์ใน TEE, FLAG_SECURE_ELEMENT — คีย์ใน StrongBox หากไม่มี flags แสดงว่าคีย์เป็นซอฟต์แวร์เท่านั้น

จะเกิดอะไรขึ้นเมื่อลบเทมเพลตไบโอเมตริกทั้งหมด?

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

Android KeyStore รองรับการสำรองข้อมูลคีย์หรือไม่?

คีย์ฮาร์ดแวร์ (ใน TEE/StrongBox) ไม่รองรับการสำรองข้อมูล — คีย์เหล่านี้ผูกติดกับอุปกรณ์เฉพาะ คีย์ซอฟต์แวร์สามารถรวมอยู่ในการสำรองข้อมูล Google Drive ในการถ่ายโอนข้อมูลระหว่างอุปกรณ์ ให้เข้ารหัสข้อมูลบนเซิร์ฟเวอร์และถอดรหัสบนอุปกรณ์ใหม่

สรุป

  • Android KeyStore — ผู้ให้บริการ JCA สำหรับจัดเก็บคีย์แบบแยกฮาร์ดแวร์ผ่าน Keymaster HAL ใน TEE/StrongBox
  • KeyGenParameterSpec กำหนดค่าอัลกอริทึม ขนาด วัตถุประสงค์ digest ไบโอเมตริก และข้อจำกัดตามเวลาของคีย์
  • RSA (KM 1.0+), EC (KM 1.0+), AES (KM 2.0+), ChaCha20 (KM 3.0+) — อัลกอริทึมที่รองรับด้วยระดับ Keymaster ที่แตกต่างกัน
  • Key Attestation (API 28+) ช่วยให้ฝั่งเซิร์ฟเวอร์ตรวจสอบแหล่งที่มาของฮาร์ดแวร์ของคีย์
  • การป้องกันคีย์แบบไบโอเมตริกผ่าน setUserAuthenticationRequired + BiometricPrompt กับ CryptoObject
  • การทำให้คีย์ไม่ถูกต้องเมื่อเปลี่ยนไบโอเมตริกป้องกันการใช้ลายนิ้วมือที่เพิ่มโดยไม่ได้รับอนุญาต
  • ใช้ Android KeyStore สำหรับสร้างและจัดเก็บคีย์เข้ารหัสด้วยการป้องกันฮาร์ดแวร์ในแอปพลิเคชัน Android

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

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

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

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