EncryptedSharedPreferences: คืออะไร API และวิธีใช้งาน

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

EncryptedSharedPreferences เป็นคอมโพเนนต์ของไลบรารี AndroidX Security ที่ให้การเข้ารหัสข้อมูลอย่างโปร่งใสซึ่งบันทึกผ่าน API SharedPreferences ต่างจาก SharedPreferences ทั่วไปที่ข้อมูลถูกเก็บในไฟล์ XML ธรรมดา EncryptedSharedPreferences จะเข้ารหัสคีย์และค่าโดยอัตโนมัติก่อนเขียนลงดิสก์ ตาม Android Developers ไลบรารีใช้ AES-256 GCM สำหรับค่าและ AES-256 SIV (RFC 5297) สำหรับคีย์ เพื่อรับประกันความลับและความสมบูรณ์ของข้อมูล

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

  • EncryptedSharedPreferences — ตัวห่อหุ้ม SharedPreferences พร้อมการเข้ารหัสอัตโนมัติของข้อมูลที่บันทึกทั้งหมด
  • การเข้ารหัส ใช้ AES-256 GCM สำหรับค่าและ AES-256 SIV สำหรับคีย์ผ่าน Android Keystore
  • Authenticated Encryption (AEAD) รับประกันว่าข้อมูลไม่ถูกเปลี่ยนแปลงหลังจากเขียน
  • Master Key ถูกเก็บใน Android Keystore และป้องกันด้วยฮาร์ดแวร์บนอุปกรณ์ที่มี TEE
  • API เข้ากันได้อย่างสมบูรณ์ กับ SharedPreferences — การแทนที่เกิดขึ้นโดยไม่ต้องเปลี่ยนโค้ดการอ่านและเขียน

EncryptedSharedPreferences คืออะไร?

EncryptedSharedPreferences เป็นคลาสจากแพ็คเกจ androidx.security.crypto ที่เปิดตัวใน AndroidX Security 1.0.0 (2019) มันใช้อินเทอร์เฟส SharedPreferences แต่การดำเนินการเขียนทั้งหมด (putString, putInt, putBoolean ฯลฯ) จะเข้ารหัสข้อมูลล่วงหน้า และการดำเนินการอ่านจะถอดรหัสข้อมูลก่อนส่งคืน

ปัญหาของ SharedPreferences ทั่วไป

SharedPreferences มาตรฐานบันทึกข้อมูลในไฟล์ XML ในไดเรกทอรีของแอป (/data/data/package/shared_prefs/) ไฟล์ไม่ได้ถูกเข้ารหัส — ด้วยการเข้าถึง root ไปยังอุปกรณ์หรือระหว่างการวิเคราะห์ข้อมูลสำรอง ข้อมูลทั้งหมดจะถูกอ่านเป็น XML ธรรมดา โทเค็นการยืนยันตัวตน คีย์ API และข้อมูลส่วนตัวของผู้ใช้กลายเป็นสิ่งที่ผู้โจมตีสามารถเข้าถึงได้

EncryptedSharedPreferences แก้ปัญหานี้ในระดับไลบรารี: ข้อมูลถูกเข้ารหัสก่อนเขียนลงดิสก์และถอดรหัสเมื่ออ่าน นักพัฒนาไม่จำเป็นต้องเรียกใช้ฟังก์ชันการเข้ารหัสด้วยตนเอง — API ยังคงเหมือนกับ SharedPreferences ทั่วไป

ประวัติและเวอร์ชัน

ไลบรารี AndroidX Security v1.0.0 เปิดตัวในเดือนธันวาคม 2019 EncryptedSharedPreferences แทนที่วิธีการเข้ารหัสด้วยตนเองที่ล้าสมัยผ่าน Cipher + SharedPreferences เวอร์ชันเสถียรปัจจุบันคือ 1.1.0-alpha06 (2024) รองรับ API 19+ ไลบรารีเป็นส่วนหนึ่งของ Jetpack และไม่ต้องได้รับอนุญาตเพิ่มเติม

ตาม Google Security Blog (2024) EncryptedSharedPreferences เป็นวิธีที่แนะนำในการเก็บการตั้งค่าแอปที่ละเอียดอ่อนซึ่งไม่ต้องการการซิงค์ผ่านคลาวด์ สำหรับสถานการณ์ที่ซับซ้อนมากขึ้น Room ที่มีการเข้ารหัส SQLCipher เป็นที่แนะนำ

EncryptedSharedPreferences ทำงานอย่างไร?

EncryptedSharedPreferences ใช้รูปแบบการเข้ารหัสสองระดับ: Master Key ถูกเก็บใน Android Keystore และใช้คีย์ที่ได้รับสำหรับการเข้ารหัสข้อมูล ซึ่งรวมการป้องกันของ Keystore เข้ากับประสิทธิภาพของการเข้ารหัสแบบสมมาตร

รูปแบบการเข้ารหัส: AES-256 GCM + SIV

สำหรับค่า ใช้ AES-256 GCM (โหมด Galois/Counter) — โหมดการเข้ารหัสที่รับรองความถูกต้อง (AEAD) ซึ่งรับประกันความลับและความสมบูรณ์ของข้อมูล สำหรับคีย์ (ชื่อพารามิเตอร์) ใช้ AES-256 SIV (RFC 5297) — การเข้ารหัสแบบกำหนดแน่นอนที่จำเป็นสำหรับการค้นหาคีย์โดยไม่เปิดเผยเนื้อหา

แต่ละไฟล์ของ EncryptedSharedPreferences ประกอบด้วยคู่คีย์-ค่าที่เข้ารหัส โครงสร้างไฟล์ประกอบด้วย: ส่วนหัวพร้อมข้อมูลเมตา (เวอร์ชัน ตัวระบุคีย์) จากนั้นรายการของรายการที่เข้ารหัส ไฟล์ไม่ใช่ XML ที่ถูกต้องและไม่สามารถอ่านได้ด้วยโปรแกรมแก้ไขข้อความ

MasterKey และ KeyStore

คลาส MasterKey รับผิดชอบในการสร้างและจัดการคีย์หลัก 256 บิตที่เก็บใน Android Keystore MasterKey.Builder อนุญาตให้กำหนดค่า: ประเภทพื้นที่เก็บข้อมูล (Keystore หรือซอฟต์แวร์) การป้องกันด้วยไบโอเมตริกซ์ และอายุของคีย์ โดยค่าเริ่มต้น คีย์หลักจะถูกสร้างใน Android Keystore ด้วยอัลกอริธึม AES/GCM/NoPadding

kotlin
import androidx.security.crypto.MasterKey
import androidx.security.crypto.EncryptedSharedPreferences

fun getEncryptedPrefs() {
    val masterKey = MasterKey.Builder(context)
        .setKeyScheme(MasterKey.AES256_GCM_SPEC)
        .build()

    val prefs = EncryptedSharedPreferences.create(
        context,
        "secure_prefs",
        masterKey,
        EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV,
        EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM
    )
}

การตั้งค่าและกำหนดค่าการเข้ารหัส

EncryptedSharedPreferences.create รับพารามิเตอร์ห้าตัว: บริบท ชื่อไฟล์ คีย์หลัก รูปแบบการเข้ารหัสคีย์ และรูปแบบการเข้ารหัสค่า การเลือกรูปแบบส่งผลต่อประสิทธิภาพและระดับความปลอดภัย

รูปแบบการเข้ารหัสคีย์

AES256_SIV — การเข้ารหัสแบบกำหนดแน่นอน: คีย์ที่เหมือนกันจะสร้างข้อความเข้ารหัสเดียวกันเสมอ ซึ่งจำเป็นสำหรับการค้นหาคีย์ (SharedPreferences.getX(key)) ข้อเสีย: ผู้โจมตีสามารถระบุได้ว่าคีย์ใดถูกใช้โดยการเปรียบเทียบข้อความเข้ารหัสที่ซ้ำกัน AES256_SIV2 — เวอร์ชันที่ปรับปรุงแล้วพร้อมการสุ่มเพิ่มเติม

สำหรับค่า ใช้ AES256_GCM GCM เพิ่ม IV 12 ไบต์ (เวกเตอร์เริ่มต้น) และแท็กรับรองความถูกต้อง 16 ไบต์ให้กับแต่ละค่า ซึ่งให้ความลับ (ไม่มีใครสามารถอ่านค่าได้) และการรับรองความถูกต้อง (ไม่มีใครสามารถแก้ไขค่าโดยไม่ถูกตรวจพบ)

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

เมธอด setUserAuthenticationRequired(true) ใน MasterKey.Builder ต้องการการยืนยันด้วยไบโอเมตริกซ์ก่อนดึงคีย์หลักจาก Keystore ซึ่งเพิ่มชั้นป้องกันเพิ่มเติม: แม้แอปกำลังทำงานบนอุปกรณ์ที่ปลดล็อกแล้ว ผู้โจมตีก็ไม่สามารถอ่าน EncryptedSharedPreferences โดยไม่มี Face ID หรือ Touch ID

สำคัญ: ด้วย setUserAuthenticationRequired คีย์หลักจะไม่สามารถใช้ได้หากผู้ใช้เปลี่ยนแปลงหรือลบข้อมูลไบโอเมตริกซ์ ต้องจัดการ KeyPermanentlyInvalidatedException และสร้างคีย์หลักใหม่พร้อมการย้ายข้อมูล

kotlin
fun createBiometricKey(): MasterKey {
    return MasterKey.Builder(context)
        .setKeyScheme(MasterKey.AES256_GCM_SPEC)
        .setUserAuthenticationRequired(true)
        .setRequestStrongBoxBacked(true)
        .build()
}

fun writeSecureToken(token: String) {
    try {
        prefs.edit().putString("auth_token", token).apply()
    } catch (e: KeyPermanentlyInvalidatedException) {
        // ข้อมูลไบโอเมตริกซ์เปลี่ยนแปลงแล้ว — จำเป็นต้องสร้างคีย์ใหม่
    }
}

ตัวอย่างการใช้งานใน Kotlin

มาดูตัวอย่างแบบสมบูรณ์ของการรวม EncryptedSharedPreferences ในแอป Android โดยใช้ Kotlin กัน ไลบรารี androidx.security:security-crypto ถูกเพิ่มผ่าน Gradle

การเพิ่ม dependencies

ในไฟล์ build.gradle (app) ให้เพิ่ม: implementation “androidx.security:security-crypto:1.1.0-alpha06” สำหรับโปรเจกต์ Kotlin ต้องใช้ kotlin-stdlib ด้วย การเริ่มต้น MasterKey เกิดขึ้นครั้งเดียว โดยปกติใน Application.onCreate หรือผ่านคอนเทนเนอร์ DI

การอ่านและเขียนข้อมูล

หลังจากสร้างอินสแตนซ์ EncryptedSharedPreferences แล้ว API ก็ไม่แตกต่างจาก SharedPreferences ทั่วไป edit() ส่งคืน Editor เมธอดทั้งหมด (putString, getString, putBoolean, getBoolean) ทำงานเหมือนกัน ข้อแตกต่างเพียงอย่างเดียวคือภายใน: ข้อมูลถูกเข้ารหัสเมื่อเขียนและถอดรหัสเมื่ออ่าน

kotlin
class AuthRepository(context: Context) {
    private val prefs = createEncryptedPrefs(context)

    fun saveCredentials(login: String, password: String) {
        prefs.edit()
            .putString("login", login)
            .putString("password", password)
            .apply()
    }

    fun getToken(): String? {
        return prefs.getString("auth_token", null)
    }

    fun clearAll() {
        prefs.edit().clear().apply()
    }
}

การย้ายจาก SharedPreferences ทั่วไป

เพื่อย้ายข้อมูลที่มีอยู่จาก SharedPreferences ที่ไม่ได้เข้ารหัสไปยัง EncryptedSharedPreferences: อ่านข้อมูลทั้งหมดจากไฟล์เก่า สร้าง EncryptedSharedPreferences ใหม่ เขียนข้อมูลทั้งหมด และลบไฟล์เก่า Google ไม่มีตัวย้ายข้อมูลในตัว — นักพัฒนาต้องimplementด้วยตนเอง

เปรียบเทียบกับ SharedPreferences ทั่วไป

การเลือกระหว่าง SharedPreferences และ EncryptedSharedPreferences ขึ้นอยู่กับประเภทของข้อมูลที่เก็บ สำหรับการตั้งค่าอินเทอร์เฟส (ธีม ภาษา การเรียงลำดับ) SharedPreferences ทั่วไปก็เพียงพอ สำหรับข้อมูลที่เป็นความลับ (โทเค็น รหัสผ่าน คีย์) จำเป็นต้องใช้ EncryptedSharedPreferences

ประสิทธิภาพ

EncryptedSharedPreferences ช้ากว่าทั่วไปเนื่องจากการดำเนินการเข้ารหัส การเขียนค่าสตริงเดียวใช้เวลา ~5-15 มิลลิวินาที (ขึ้นอยู่กับขนาดข้อมูลและการเร่งด้วยฮาร์ดแวร์ AES) การอ่านใช้เวลา 2-5 มิลลิวินาที สำหรับแอปส่วนใหญ่นี้ไม่สังเกตเห็น แต่สำหรับการดำเนินการแบบกลุ่ม (การย้าย การกู้คืน) ให้ใช้ apply() แทน commit()

ความปลอดภัย

SharedPreferences ทั่วไปไม่มีการป้องกันการเข้ารหัสใด ๆ: ไฟล์ XML สามารถอ่านได้โดยกระบวนการใด ๆ ที่มีสิทธิ์ root หรือผ่าน adb backup EncryptedSharedPreferences เข้ารหัสข้อมูลในระดับแอปพลิเคชัน และคีย์หลักถูกเก็บใน Android Keystore พร้อมการป้องกันด้วยฮาร์ดแวร์เพิ่มเติม (StrongBox)

คุณลักษณะSharedPreferencesEncryptedSharedPreferences
การเก็บXML ธรรมดาไฟล์ไบนารีที่เข้ารหัส
การเข้ารหัสไม่มีAES-256 GCM + SIV
การป้องกันคีย์ไม่มีAndroid Keystore + StrongBox
ประสิทธิภาพ0.1-1 มิลลิวินาที2-15 มิลลิวินาที
คำแนะนำการตั้งค่า UIโทเค็น, คีย์, PII

เมื่อใดควรเลือก EncryptedSharedPreferences

ใช้ EncryptedSharedPreferences เพื่อเก็บ: โทเค็นรีเฟรช OAuth, คีย์ API สำหรับบริการภายนอก, อีเมลหรือเบอร์โทรศัพท์ของผู้ใช้ และการตั้งค่าแอปที่ละเอียดอ่อน (PIN, แฟล็กการยืนยันตัวตน) EncryptedSharedPreferences ไม่เหมาะสำหรับการเก็บข้อมูลไบโอเมตริกซ์หรือเอกสารขนาดใหญ่ — ให้ใช้ EncryptedFile หรือ Room กับ SQLCipher แทน

กฎทั่วไป: หากข้อมูลรั่วไหลจะเป็นอันตรายต่อผู้ใช้หรือธุรกิจ — ใช้ EncryptedSharedPreferences หากข้อมูลเป็นเพียงความสวยงาม (ธีม ภาษา การเรียงลำดับ) — SharedPreferences ทั่วไป การนำ EncryptedSharedPreferences มาใช้ตั้งแต่ต้นนั้นสมเหตุสมผล โดยไม่ต้องปรับโครงสร้าง: การแทนที่ในโปรเจกต์ที่มีอยู่จะต้องมีการย้ายข้อมูลและการจัดการข้อมูลเก่าที่ยังไม่ได้เข้ารหัส

โปรดจำไว้ว่า EncryptedSharedPreferences ไม่ได้ปกป้องข้อมูลระหว่างที่แอปทำงาน — เฉพาะบนดิสก์เท่านั้น หากผู้โจมตีเข้าถึงหน่วยความจำของกระบวนการ ข้อมูลที่ถอดรหัสแล้วอาจถูกดักจับได้ ใช้การป้องกันเพิ่มเติม: ProGuard/DexGuard สำหรับการทำให้โค้ดสับสน

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

EncryptedSharedPreferences แตกต่างจาก DataStore อย่างไร?

Jetpack DataStore เป็นทางเลือกที่ทันสมัยกว่าของ SharedPreferences ซึ่งใช้ Flow และ coroutine ของ Kotlin DataStore ไม่ได้เข้ารหัสข้อมูลโดยค่าเริ่มต้น แต่สามารถรวมกับ EncryptedSharedPreferences หรือใช้กับการเข้ารหัสด้วยตนเองผ่าน Proto DataStore กับโปรโตคอลการเข้ารหัส

สามารถใช้ EncryptedSharedPreferences สำหรับข้อมูลปริมาณมากได้หรือไม่?

ไม่แนะนำ EncryptedSharedPreferences ถูกออกแบบมาสำหรับปริมาณน้อย (สูงสุด 100-200 KB) สำหรับข้อมูลที่ใหญ่ขึ้น ให้ใช้ Room กับ SQLCipher หรือการเข้ารหัสไฟล์ผ่าน EncryptedFile จากไลบรารี AndroidX Security เดียวกัน

EncryptedSharedPreferences รองรับการย้ายเมื่ออัปเดต schema หรือไม่?

ไม่ ไม่มีการย้าย schema อัตโนมัติ เมื่อเปลี่ยนโครงสร้างข้อมูล นักพัฒนาต้องอ่านข้อมูลเก่าด้วยตนเองผ่าน KeyGen เก่าและเขียนผ่าน KeyGen ใหม่ แนะนำให้เก็บเวอร์ชัน schema ไว้ในพารามิเตอร์แยกต่างหาก

ระดับ API ขั้นต่ำที่ต้องการคือเท่าใด?

AndroidX Security 1.0.0 รองรับ API 19+ (Android KitKat) เวอร์ชัน 1.1.0-alpha06 ก็รองรับ API 19+ เช่นกัน StrongBox ต้องการ API 28+ และอุปกรณ์ที่รองรับฮาร์ดแวร์ (Google Pixel 3+, Samsung Galaxy S9+)

การเก็บ refresh token ใน EncryptedSharedPreferences ปลอดภัยหรือไม่?

ใช่ refresh token เป็นหนึ่งในกรณีการใช้งานหลัก การเข้ารหัส AES-256 GCM, คีย์หลักใน Keystore, การป้องกันด้วยไบโอเมตริกซ์ — ระดับที่เพียงพอสำหรับโทเค็น OAuth สำหรับ access token ที่มีอายุสั้นก็เหมาะสมเช่นกัน แม้ว่าบางทีมจะชอบเก็บไว้ในหน่วยความจำ

สรุป

  • EncryptedSharedPreferences — ตัวห่อหุ้ม SharedPreferences พร้อมการเข้ารหัสอัตโนมัติผ่าน AES-256 GCM (ค่า) และ SIV (คีย์)
  • Master Key ถูกสร้างผ่าน MasterKey.Builder และเก็บใน Android Keystore พร้อมตัวเลือกไบโอเมตริกซ์และ StrongBox
  • API เข้ากันได้อย่างสมบูรณ์: edit, putString, getString, apply, clear — ทั้งหมดเหมือน SharedPreferences ทั่วไป
  • ประสิทธิภาพ: 2-15 มิลลิวินาทีต่อการดำเนินการ ผู้ใช้ไม่สังเกตเห็นในสถานการณ์มาตรฐาน
  • ความปลอดภัย: การเข้ารหัสที่รับรองความถูกต้อง (AEAD) ป้องกันทั้งการอ่านและการปลอมแปลงข้อมูล
  • การย้ายข้อมูลจาก SharedPreferences ทั่วไปต้องถ่ายโอนข้อมูลด้วยตนเองผ่านไฟล์เก่าและใหม่
  • ใช้ EncryptedSharedPreferences สำหรับโทเค็น, คีย์ API, รหัสผ่าน และการตั้งค่าที่ละเอียดอ่อนอื่น ๆ

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

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

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

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