Secure Storage — ชุดของวิธีการและเทคโนโลยีสำหรับปกป้องข้อมูลที่เป็นความลับบนอุปกรณ์: โทเคน, คีย์เข้ารหัส, ข้อมูลการชำระเงิน และข้อมูลส่วนบุคคลของผู้ใช้ ตามข้อมูลจาก OWASP Mobile Top 10 (2024) การจัดเก็บข้อมูลที่ไม่ปลอดภัยอยู่ในสามอันดับแรกของความเสี่ยงที่ร้ายแรงที่สุด การนำ Secure Storage ไปใช้อย่างถูกต้องจะป้องกันการรั่วไหลของข้อมูลแม้เมื่อมีผู้เข้าถึงอุปกรณ์ทางกายภาพ
ประเด็นสำคัญ
Secure Storage — แนวปฏิบัติในการจัดเก็บข้อมูลที่เป็นความลับของแอปพลิเคชันมือถือในลักษณะที่แอปพลิเคชันอื่น ซอฟต์แวร์อันตราย และผู้ไม่หวังดีไม่สามารถเข้าถึงได้แม้จะเข้าถึงอุปกรณ์ทางกายภาพ แตกต่างจากการจัดเก็บทั่วไป Secure Storage ใช้การเข้ารหัส การแยก และการป้องกันในระดับฮาร์ดแวร์
ไม่ใช่ข้อมูลทั้งหมดที่ต้องการ Secure Storage: รูปภาพโปรไฟล์หรือแคชข่าวสามารถเก็บในระบบไฟล์ปกติ อย่างไรก็ตาม คีย์เข้ารหัส โทเคนยืนยันตัวตน ข้อมูลการชำระเงิน คีย์ส่วนตัว และแม่แบบไบโอเมตริกต้องได้รับการปกป้อง ตามข้อมูลจาก Google Security Blog (2025) 67% ของช่องโหว่ในแอปพลิเคชันมือถือเกี่ยวข้องกับการจัดเก็บความลับในรูปแบบเปิด
แต่ละแพลตฟอร์มมือถือมีกลไก Secure Storage ของตนเอง: Android — Keystore และ EncryptedSharedPreferences, iOS — Keychain และ Data Protection API กลไกเหล่านี้ถูกรวมเข้ากับโมดูลความปลอดภัยของฮาร์ดแวร์ (TEE, Secure Enclave) และรับประกันว่าไม่สามารถอ่านข้อมูลได้แม้จะเจลเบรกหรือรูทอุปกรณ์
การเลือกวิธี Secure Storage ที่ถูกต้องขึ้นอยู่กับประเภทของข้อมูล สถานการณ์การใช้งาน และข้อกำหนดด้านประสิทธิภาพ การเข้าใจสถาปัตยกรรมของแต่ละกลไกช่วยให้นักพัฒนาสามารถตัดสินใจทางสถาปัตยกรรมที่ถูกต้องได้
แพลตฟอร์ม Android มีการป้องกันข้อมูลหลายระดับ ตั้งแต่คลังเก็บคีย์ระดับฮาร์ดแวร์ไปจนถึง SharedPreferences ที่เข้ารหัส การเลือกขึ้นอยู่กับความไวของข้อมูลและข้อกำหนดด้านประสิทธิภาพ
Android Keystore เป็นผู้ให้บริการเข้ารหัสที่สร้างและจัดเก็บคีย์ในสภาพแวดล้อมการทำงานแบบแยก (TEE — Trusted Execution Environment) บนอุปกรณ์ที่รองรับการป้องกันระดับฮาร์ดแวร์ คีย์จะไม่ออกจาก TEE: การดำเนินการเข้ารหัสจะเกิดขึ้นภายในพื้นที่ที่ได้รับการป้องกัน ซึ่งแม้แต่ระบบปฏิบัติการก็ไม่สามารถเข้าถึงได้
ตั้งแต่ Android 9 (API 28) Keystore รองรับ StrongBox Keymaster — ชิปความปลอดภัยเฉพาะที่มี CPU ของตัวเอง True Random Number Generator (TRNG) และหน่วยความจำที่ได้รับการป้องกัน StrongBox ได้รับการรับรองตาม Common Criteria EAL 4+ และเป็นระดับการจัดเก็บคีย์ที่ปลอดภัยที่สุดบน Android การใช้ StrongBox ต้องระบุแฟล็ก inStrongBox() อย่างชัดเจนเมื่อสร้างคีย์
Keystore รองรับอัลกอริทึม: AES/GCM/NoPadding (256 บิต), EC (secp256r1, secp384r1), RSA (2048–4096 บิต) และ HMAC-SHA256 คีย์ทั้งหมดสามารถผูกกับการยืนยันตัวตนแบบไบโอเมตริกผ่าน setUserAuthenticationRequired(true)
EncryptedSharedPreferences เป็นไลบรารีจากแพ็กเกจ AndroidX Security ที่เข้ารหัสข้อมูลทั้งหมดที่จัดเก็บผ่าน SharedPreferences API โดยอัตโนมัติ ค่าต่างๆ จะถูกเข้ารหัสด้วยคีย์ AES-256 GCM และคีย์ต่างๆ จะถูกเข้ารหัสด้วย AES-256 SIV (Synthetic IV) ซึ่งป้องกันการโจมตีด้วยพจนานุกรมต่อชื่อคีย์
คีย์หลักในการเข้ารหัสถูกจัดเก็บใน Android Keystore ทำให้มีการป้องกันสองระดับ: Keystore ปกป้องคีย์หลัก EncryptedSharedPreferences ปกป้องข้อมูล ประสิทธิภาพการเข้ารหัสน้อยกว่า 5 มิลลิวินาทีต่อการดำเนินการอ่าน/เขียนสำหรับข้อมูลทั่วไป (โทเคน การตั้งค่า) ทำให้ไลบรารีนี้เหมาะสำหรับสถานการณ์การใช้งานของผู้ใช้
EncryptedSharedPreferences ไม่ได้ออกแบบมาสำหรับข้อมูลปริมาณมาก (มากกว่า 5 MB) — สำหรับข้อมูลดังกล่าวให้ใช้ฐานข้อมูลที่เข้ารหัสผ่าน SQLCipher หรือ Room พร้อมการเข้ารหัส
SQLCipher เป็นส่วนขยายของ SQLite ที่เข้ารหัสทั้งฐานข้อมูลทีละหน้าด้วย AES-256-CBC แต่ละหน้าของฐานข้อมูลจะถูกเข้ารหัสด้วยคีย์เฉพาะที่ได้มาจากรหัสผ่านหลักผ่าน PBKDF2 SQLCipher เพิ่มค่าใช้จ่ายด้านประสิทธิภาพประมาณ 5–15% ขึ้นอยู่กับขนาดของข้อมูล
การรวมเข้ากับ Android ทำได้ผ่านไลบรารี net.zetetic:android-database-sqlcipher ซึ่งมี API ที่เข้ากันได้กับ SQLiteOpenHelper มาตรฐาน ขอแนะนำให้จัดเก็บรหัสผ่านสำหรับ SQLCipher ไว้ใน Keystore ไม่ใช่ในโค้ดหรือ SharedPreferences
แพลตฟอร์ม iOS มี Keychain Services — คลังเก็บที่ปลอดภัยหลัก — และ Data Protection API สำหรับการเข้ารหัสไฟล์ในระดับ OS
Keychain เป็นฐานข้อมูล SQLite ที่เข้ารหัสซึ่ง iOS ใช้จัดเก็บรหัสผ่าน คีย์เข้ารหัส ใบรับรอง และบันทึกย่อ แต่ละรายการใน Keychain (SecItem) ถูกจัดเก็บในรูปแบบที่เข้ารหัสด้วยคีย์ฮาร์ดแวร์ที่ไม่ซ้ำกันสำหรับแต่ละอุปกรณ์ การเข้าถึงรายการถูกควบคุมผ่าน ACL (Access Control List) ซึ่งอาจต้องมีการยืนยันตัวตนแบบไบโอเมตริก (Face ID, Touch ID) หรือรหัสผ่าน
Keychain รองรับคลาสการป้องกัน (Protection Class) ที่กำหนดว่าข้อมูลจะพร้อมใช้งานเมื่อใด: kSecAttrAccessibleWhenUnlockedThisDeviceOnly — ข้อมูลจะพร้อมใช้งานเมื่ออุปกรณ์ปลดล็อกเท่านั้น และไม่ถูกถ่ายโอนเมื่อสำรองข้อมูล คลาสนี้แนะนำสำหรับสถานการณ์การจัดเก็บโทเคนยืนยันตัวตนส่วนใหญ่
บน iOS 15+ มี Security framework ที่รองรับคีย์ฮาร์ดแวร์ผ่าน Secure Enclave — โปรเซสเซอร์เฉพาะของ Apple ที่ดำเนินการเข้ารหัสและจัดเก็บคีย์ส่วนตัวในหน่วยความจำแบบแยก Secure Enclave รองรับอัลกอริทึม ECDSA (secp256r1) และ ECDH สำหรับการสร้างคีย์ซึ่งไม่สามารถแยกออกจากชิปได้
Data Protection เป็นกลไกของ iOS ที่เข้ารหัสแต่ละไฟล์ในระดับระบบไฟล์ (APFS) ด้วยคีย์ที่เชื่อมโยงกับรหัสผ่านของอุปกรณ์ นักพัฒนากำหนดระดับการป้องกันผ่านแอตทริบิวต์ NSFileProtectionType เมื่อสร้างไฟล์: NSFileProtectionComplete — ไฟล์จะพร้อมใช้งานเมื่ออุปกรณ์ปลดล็อกเท่านั้น
Data Protection ทำงานอัตโนมัติบนอุปกรณ์ทั้งหมดที่ใช้ iOS 5+ หากมีการตั้งรหัสผ่าน การเข้ารหัสดำเนินการในระดับฮาร์ดแวร์ผ่าน Dedicated AES Engine ของโปรเซสเซอร์ Apple ซึ่งให้ประสิทธิภาพสูง — ความล่าช้าในการเข้ารหัสแทบไม่สังเกตเห็นได้สำหรับผู้ใช้ การเปิดใช้งานการป้องกันในแอปพลิเคชัน只需ตั้งค่าแอตทริบิวต์การป้องกันเมื่อสร้างไฟล์ผ่าน FileManager
Data Protection ไม่ได้แทนที่ Keychain สำหรับการจัดเก็บคีย์ — ใช้สำหรับการเข้ารหัสไฟล์ ฐานข้อมูล Core Data และข้อมูลปริมาณมากอื่นๆ การรวมกันของ Keychain (สำหรับคีย์) และ Data Protection (สำหรับไฟล์) ให้วงจรการจัดเก็บที่ปลอดภัยสมบูรณ์บน iOS
มาดูตัวอย่างเชิงปฏิบัติของ Secure Storage โดยใช้ API ในตัวของ Android และ iOS
ตัวอย่างแสดงการเริ่มต้น EncryptedSharedPreferences ด้วยคีย์หลักจาก Android Keystore การดำเนินการอ่านและเขียนทั้งหมดหลังจากนี้จะถูกเข้ารหัสและถอดรหัสโดยอัตโนมัติ
import androidx.security.crypto.EncryptedSharedPreferences
import androidx.security.crypto.MasterKey
val masterKey = MasterKey.Builder(context)
.setKeyScheme(MasterKey.KeyScheme.AES256_GCM)
.build()
val prefs = EncryptedSharedPreferences.create(
context,
"secure_prefs",
masterKey,
EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV,
EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM
)
prefs.edit()
.putString("auth_token", "eyJhbGciOiJIUzI1NiJ9...")
.apply()
ตัวอย่างแสดงการบันทึกและอ่านข้อมูลจาก iOS Keychain โดยใช้ Security framework โค้ดใช้ kSecAttrAccessibleWhenUnlockedThisDeviceOnly เพื่อการป้องกันสูงสุด
import Security
func saveToKeychain(key: String, data: Data) {
let query: [String: Any] = [
kSecClass as String: kSecClassGenericPassword,
kSecAttrAccount as String: key,
kSecValueData as String: data,
kSecAttrAccessible as String:
kSecAttrAccessibleWhenUnlockedThisDeviceOnly
]
SecItemDelete(query as CFDictionary)
SecItemAdd(query as CFDictionary, nil)
}
func readFromKeychain(key: String) -> Data? {
let query: [String: Any] = [
kSecClass as String: kSecClassGenericPassword,
kSecAttrAccount as String: key,
kSecReturnData as String: true,
kSecMatchLimit as String: kSecMatchLimitOne
]
var result: AnyObject?
let status = SecItemCopyMatching(
query as CFDictionary, &result
)
return status == errSecSuccess ? result as? Data : nil
}
ตัวอย่างแสดงการเชื่อมต่อกับฐานข้อมูล SQLite ที่เข้ารหัสผ่าน SQLCipher ด้วยรหัสผ่านที่จัดเก็บใน Android Keystore
import net.sqlcipher.database.SQLiteDatabase
import net.sqlcipher.database.SQLiteOpenHelper
class SecureDBHelper(context: Context) :
SQLiteOpenHelper(context, "secure.db", null, 1) {
private val password = getKeyFromKeystore()
override fun onCreate(db: SQLiteDatabase) {
db.execSQL("CREATE TABLE tokens (id INTEGER PRIMARY KEY, value TEXT)")
}
override fun onUpgrade(
db: SQLiteDatabase, oldVersion: Int, newVersion: Int
) {
onCreate(db)
}
}
// การใช้งาน: ส่งรหัสผ่านเมื่อเปิด
val helper = SecureDBHelper(context)
val db = helper.getWritableDatabase(password)
การใช้ Secure Storage อย่างถูกต้องต้องปฏิบัติตามหลักการพื้นฐานหลายประการที่ป้องกันข้อผิดพลาดทั่วไปของนักพัฒนา
กำหนดการจำแนกข้อมูล: ข้อมูลใดต้องการการป้องกันระดับฮาร์ดแวร์ (Keystore / Secure Enclave) ข้อมูลใดต้องการการเข้ารหัสระดับ OS (EncryptedSharedPreferences / Data Protection) และข้อมูลใดสามารถเก็บในระบบไฟล์ปกติ โทเคนยืนยันตัวตน คีย์ส่วนตัว และข้อมูลการชำระเงิน — เฉพาะระดับฮาร์ดแวร์ การตั้งค่าผู้ใช้ (ธีม ภาษา) — EncryptedSharedPreferences ก็เพียงพอ ข้อมูลเซสชัน (แคชชั่วคราว) สามารถเก็บในหน่วยความจำหรือไดเรกทอรีชั่วคราว
อย่าจัดเก็บความลับในโค้ด: สตริงที่มีคีย์ API รหัสผ่าน หรือวลี seed ในซอร์สโค้ดเป็นข้อผิดพลาดด้านความปลอดภัยที่ร้ายแรง การรีเวิร์สเอนจิเนียริ่งจะเปิดเผยข้อมูลเหล่านี้ทันที ใช้ Keystore สำหรับคีย์ และสำหรับการกำหนดค่า — โหลดจากเซิร์ฟเวอร์เมื่อเริ่มแอปพลิเคชัน (remote config)
ใช้การผูกไบโอเมตริกสำหรับการดำเนินการที่สำคัญ: Android Keystore และ iOS Keychain รองรับการผูกคีย์กับการยืนยันตัวตนแบบไบโอเมตริก ทุกครั้งที่เข้าถึงคีย์ ระบบจะขอ Face ID, Touch ID หรือ BiometricPrompt ของ Android ซึ่งรับประกันว่าแม้ผู้ไม่หวังดีจะควบคุมอุปกรณ์ได้อย่างสมบูรณ์ ก็ไม่สามารถใช้ข้อมูลที่จัดเก็บไว้ได้หากไม่มีเจ้าของ
ทดสอบการป้องกัน: ใช้เครื่องมือวิเคราะห์ความปลอดภัย — MobSF (Mobile Security Framework) สำหรับการวิเคราะห์แบบสแตติก objection สำหรับการทดสอบขณะรันไทม์ และ Frida สำหรับการเลี่ยงการป้องกัน ตรวจสอบว่าข้อมูลไม่สามารถเข้าถึงได้หลังการรูทหรือเจลเบรก Android อนุญาตให้ตรวจสอบการเข้าถึง root ผ่าน SafetyNet Attestation หรือ Play Integrity API ส่วน iOS — ผ่านการตรวจสอบความสมบูรณ์ของ Secure Enclave
อัปเดตไลบรารีการเข้ารหัสเป็นประจำ: ช่องโหว่ในไลบรารีการเข้ารหัสถูกค้นพบเป็นประจำ ติดตาม CVE สำหรับ AndroidX Security, SQLCipher และ Keychain wrappers ใช้ระบบแจ้งเตือนอัตโนมัติเมื่อมีเวอร์ชันใหม่ผ่าน Dependabot หรือ Renovate
ตามข้อมูลจาก Apple Security Research (2025) การนำ Secure Storage ไปใช้อย่างถูกต้องสามารถป้องกันการโจมตีที่มุ่งขโมยข้อมูลจากอุปกรณ์ได้ 96% ส่วนที่เหลืออีก 4% — การโจมตีแบบเข้าถึงทางกายภาพและช่องโหว่ zero day ซึ่งการผูกไบโอเมตริกมีประสิทธิภาพในการป้องกัน
คำถามที่พบบ่อย
iOS Keychain — ฐานข้อมูลที่เข้ารหัสสำหรับจัดเก็บรหัสผ่าน คีย์ และใบรับรองพร้อมควบคุมการเข้าถึงผ่าน ACL Android Keystore — ผู้ให้บริการเข้ารหัสที่สร้างและจัดเก็บคีย์ในสภาพแวดล้อมแบบแยก (TEE/StrongBox) และไม่อนุญาตให้แยกคีย์ส่วนตัวออกมา
EncryptedSharedPreferences ใช้ AES-256 GCM สำหรับการเข้ารหัสค่าและ AES-256 SIV สำหรับการเข้ารหัสคีย์ คีย์หลักถูกจัดเก็บใน Android Keystore ทำให้มีการป้องกันสองระดับ นอกจากนี้ยังใช้ HMAC-SHA256 สำหรับการตรวจสอบความสมบูรณ์
ใช่ HTTPS ปกป้องข้อมูลเฉพาะในช่องทางการส่งข้อมูลเท่านั้น บนอุปกรณ์ ข้อมูลจะถูกจัดเก็บในรูปแบบเปิดหลังจากถอดรหัส หากผู้ไม่หวังดีเข้าถึงอุปกรณ์ทางกายภาพหรือติดตั้งซอฟต์แวร์อันตราย HTTPS จะไม่ปกป้องข้อมูลที่จัดเก็บไว้ ควรเข้ารหัสข้อมูลในระดับการจัดเก็บเสมอ
ใช้ Android Keystore ด้วยแฟล็ก setUnlockedDeviceRequired(true) ซึ่งบล็อกการเข้าถึงคีย์บนอุปกรณ์ที่รูทแล้ว นอกจากนี้ตรวจสอบความสมบูรณ์ผ่าน Play Integrity API และเมื่อพบความเบี่ยงเบนจากค่ามาตรฐาน ให้ล้างความลับทั้งหมดออกจากคลังเก็บ
ไม่ UserDefaults จัดเก็บข้อมูลในรูปแบบเปิดในไฟล์ plist ภายในแซนด์บ็อกซ์ แอปพลิเคชันใดๆ ที่มีเครื่องมือรีเวิร์สเอนจิเนียริ่ง (ผ่านการสำรองข้อมูลหรือเจลเบรก) สามารถอ่านโทเคนได้ มีเพียง Keychain เท่านั้นที่เป็นที่จัดเก็บความลับที่ปลอดภัยบน iOS
สรุป
เราจะพัฒนาแอปพลิเคชันบนมือถือแบบครบวงจร
IT Sectr สร้างแอปพลิเคชัน iOS และ Android สำหรับสตาร์ทอัพและธุรกิจตั้งแต่ปี 2017 เราจะให้คำแนะนำและเสนอวิธีแก้ปัญหาที่ดีที่สุดแก่คุณ
อ่านเพิ่มเติม