التخزين الآمن (Secure Storage) هو مجموعة من الأساليب والتقنيات لحماية البيانات السرية على الجهاز: الرموز المميزة ومفاتيح التشفير ومعلومات الدفع والبيانات الشخصية للمستخدمين. وفقاً لـ OWASP Mobile Top 10 (2024)، يُعد تخزين البيانات غير الآمن من بين أهم ثلاثة مخاطر حرجة. التنفيذ الصحيح لـ التخزين الآمن يمنع تسرب البيانات حتى مع الوصول المادي إلى الجهاز.
الرئيسية
التخزين الآمن هو ممارسة تخزين البيانات السرية لتطبيق محمول بطريقة تجعلها غير قابلة للوصول من التطبيقات الأخرى والبرامج الضارة والمهاجمين ذوي الوصول المادي إلى الجهاز. على عكس التخزين العادي، يستخدم التخزين الآمن التشفير والعزل والحماية عبر الأجهزة.
ليست كل البيانات تحتاج إلى تخزين آمن: يمكن تخزين صور الملف الشخصي أو ذاكرة التخزين المؤقت للأخبار في نظام الملفات العادي. ومع ذلك، يجب حماية مفاتيح التشفير ورموز المصادقة وبيانات الدفع والمفاتيح الخاصة والقوالب البيومترية. وفقاً لـ Google Security Blog (2025)، يرتبط 67% من الثغرات الأمنية في التطبيقات المحمولة بتخزين الأسرار كنص عادي.
توفر كل منصة محمولة آليات التخزين الآمن الخاصة بها: Android — Keystore و EncryptedSharedPreferences، iOS — Keychain و Data Protection API. هذه الآليات مدمجة مع وحدات أمان الأجهزة (TEE, Secure Enclave) وتضمن عدم إمكانية قراءة البيانات حتى بعد كسر الحماية أو تجذير الجهاز.
يعتمد الاختيار الصحيح لطريقة التخزين الآمن على نوع البيانات وسيناريو الاستخدام ومتطلبات الأداء. فهم بنية كل آلية يسمح للمطور باتخاذ القرار المعماري الصحيح.
توفر منصة Android عدة مستويات لحماية البيانات، من تخزين المفاتيح عبر الأجهزة إلى SharedPreferences المشفرة. يعتمد الاختيار على حساسية البيانات ومتطلبات الأداء.
Android Keystore هو موفر تشفير يقوم بإنشاء وتخزين المفاتيح في بيئة تنفيذ معزولة (TEE — Trusted Execution Environment) على الأجهزة التي تدعم الحماية عبر الأجهزة. المفاتيح لا تترك TEE أبداً: يتم تنفيذ العمليات التشفيرية داخل منطقة محمية غير قابلة للوصول حتى لنظام التشغيل.
بدءاً من Android 9 (API 28)، يدعم Keystore StrongBox Keymaster — شريحة أمان مخصصة بوحدة معالجة مركزية خاصة بها ومولد أرقام عشوائية حقيقي (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 تلقائياً. يتم تشفير القيم بمفتاح AES-256 GCM، ويتم تشفير المفاتيح بـ AES-256 SIV (IV اصطناعي)، مما يمنع هجمات القاموس على أسماء المفاتيح.
يتم تخزين مفتاح التشفير الرئيسي في Android Keystore، مما يوفر حماية من مستويين: Keystore يحمي المفتاح الرئيسي، EncryptedSharedPreferences تحمي البيانات. أداء التشفير أقل من 5 مللي ثانية لكل عملية قراءة/كتابة للبيانات النموذجية (رمز مميز، إعدادات)، مما يجعل المكتبة مناسبة لسيناريوهات المستخدم.
EncryptedSharedPreferences غير مصممة لأحجام كبيرة من البيانات (أكثر من 5 ميجابايت) — لذلك، استخدم قاعدة بيانات مشفرة عبر SQLCipher أو Room مع التشفير.
SQLCipher هو امتداد لـ SQLite يقوم بتشفير قاعدة البيانات بأكملها صفحة بصفحة باستخدام AES-256-CBC. يتم تشفير كل صفحة من قاعدة البيانات بمفتاح منفصل مشتق من كلمة المرور الرئيسية عبر PBKDF2. SQLCipher يضيف حوالي 5–15% من الحمل الإضافي على الأداء حسب حجم البيانات.
يتم التكامل مع Android عبر المكتبة net.zetetic:android-database-sqlcipher التي توفر واجهة برمجة تطبيقات متوافقة مع SQLiteOpenHelper القياسي. يُوصى بتخزين كلمة مرور SQLCipher في Keystore، وليس في الكود أو SharedPreferences.
توفر منصة iOS Keychain Services كمتجر آمن رئيسي، بالإضافة إلى واجهة برمجة تطبيقات Data Protection لتشفير الملفات على مستوى نظام التشغيل.
Keychain هي قاعدة بيانات SQLite مشفرة حيث يخزن iOS كلمات المرور ومفاتيح التشفير والشهادات والملاحظات. يتم تخزين كل عنصر في Keychain (SecItem) بشكل مشفر باستخدام مفتاح أجهزة فريد للجهاز. يتم التحكم في الوصول إلى العنصر عبر ACL (قائمة التحكم في الوصول)، والتي يمكن أن تتطلب مصادقة بيومترية (Face ID, Touch ID) أو رمز مرور.
يدعم Keychain فئات حماية تحدد متى تكون البيانات قابلة للوصول: kSecAttrAccessibleWhenUnlockedThisDeviceOnly — البيانات قابلة للوصول فقط عند فتح قفل الجهاز ولا يتم نقلها أثناء النسخ الاحتياطي. يُوصى بهذه الفئة لمعظم سيناريوهات تخزين رموز المصادقة.
على iOS 15+، يتوفر Security framework مع دعم المفاتيح عبر الأجهزة من خلال Secure Enclave — معالج Apple مخصص يقوم بمعالجة العمليات التشفيرية وتخزين المفاتيح الخاصة في ذاكرة معزولة. يدعم Secure Enclave خوارزميات ECDSA (secp256r1) و ECDH لإنشاء مفاتيح لا يمكن استخراجها من الشريحة.
Data Protection هي آلية iOS تقوم بتشفير كل ملف على مستوى نظام الملفات (APFS) باستخدام مفتاح مرتبط برمز مرور الجهاز. يحدد المطور مستوى الحماية عبر سمة NSFileProtectionType عند إنشاء ملف: NSFileProtectionComplete — الملف قابل للوصول فقط عند فتح قفل الجهاز.
Data Protection تعمل تلقائياً على جميع الأجهزة التي تعمل بنظام iOS 5+ إذا تم تعيين رمز مرور. يتم التشفير على مستوى الأجهزة عبر محرك AES المخصص من Apple، مما يضمن أداء عالياً — زمن انتقال التشفير غير ملحوظ تقريباً للمستخدم. لتفعيل الحماية في تطبيق، يكفي تعيين سمة الحماية عند إنشاء ملف عبر FileManager.
Data Protection لا تحل محل Keychain لتخزين المفاتيح — تُستخدم لتشفير الملفات وقواعد بيانات Core Data والأحجام الكبيرة الأخرى من البيانات. يوفر الجمع بين Keychain (للمفاتيح) و Data Protection (للملفات) دورة كاملة للتخزين الآمن على iOS.
دعونا نلقي نظرة على أمثلة عملية لـ التخزين الآمن باستخدام واجهات برمجة التطبيقات المدمجة في 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)
الاستخدام الصحيح لـ التخزين الآمن يتطلب اتباع عدة مبادئ أساسية تمنع الأخطاء الشائعة للمطورين.
حدد تصنيف البيانات: أي البيانات تتطلب حماية عبر الأجهزة (Keystore / Secure Enclave)، وأيها تتطلب تشفيراً على مستوى نظام التشغيل (EncryptedSharedPreferences / Data Protection)، وأيها يمكن تخزينها في نظام الملفات العادي. رموز المصادقة والمفاتيح الخاصة وبيانات الدفع — مستوى الأجهزة فقط. إعدادات المستخدم (السمة، اللغة) — EncryptedSharedPreferences كافية. بيانات الجلسة (الذاكرة المؤقتة) يمكن تخزينها في الذاكرة أو دليل مؤقت.
لا تخزن الأسرار في الكود أبداً: السلاسل النصية مع مفاتيح API أو كلمات المرور أو عبارات البذور في الكود المصدري هي خطأ أمني فادح. أي هندسة عكسية ستكشف هذه البيانات فوراً. استخدم Keystore للمفاتيح، وللتكوين — التحميل من الخادم عند بدء تشغيل التطبيق (التكوين عن بُعد).
استخدم الربط البيومتري للعمليات الحرجة: Android Keystore و iOS Keychain يدعمان ربط المفاتيح بالمصادقة البيومترية. في كل مرة يتم الوصول إلى مفتاح، يطلب النظام Face ID أو Touch ID أو القياسات الحيوية لنظام Android (BiometricPrompt). هذا يضمن أنه حتى مع السيطرة الكاملة على الجهاز، لا يمكن للمهاجم استخدام البيانات المخزنة دون المالك.
اختبر الأمان: استخدم أدوات تحليل الأمان — MobSF (Mobile Security Framework) للتحليل الثابت، objection للاختبار في وقت التشغيل و Frida لتجاوز الحماية. تحقق من أن البيانات غير قابلة للوصول بعد التجذير أو كسر الحماية. Android يسمح بالتحقق من وجود الوصول الجذر عبر SafetyNet Attestation أو Play Integrity API، iOS — عبر التحقق من سلامة Secure Enclave.
قم بتحديث المكتبات التشفيرية بانتظام: يتم اكتشاف الثغرات الأمنية في مكتبات التشفير بانتظام. تابع CVEs لـ AndroidX Security و SQLCipher وأغلفة Keychain. نفذ نظام إشعارات تلقائي للإصدارات الجديدة عبر Dependabot أو Renovate.
وفقاً لـ Apple Security Research (2025)، التنفيذ الصحيح للتخزين الآمن يمنع 96% من الهجمات التي تستهدف سرقة البيانات من الجهاز. النسبة المتبقية 4% هي هجمات مع وصول مادي وثغرات يوم الصفر، والتي يكون الربط البيومتري فعالاً ضدها.
الأسئلة الشائعة
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 داخل بيئة الحماية (sandbox). أي تطبيق بأدوات الهندسة العكسية (عبر النسخ الاحتياطي أو كسر الحماية) يمكنه قراءة الرموز المميزة. Keychain فقط هو المكان الآمن الوحيد لتخزين الأسرار على iOS.
الخلاصة
سنقوم بتطوير تطبيق جوال جاهز
تقدم IT Sectr تطبيقات iOS وAndroid للشركات الناشئة والشركات منذ عام 2017. سوف نقدم لك النصح ونقترح أفضل حل.
اقرأ أيضًا