تطوير Android / المتقدم: أنظمة محمولة وإصدارات موثوقة / الدرس 16
حدود الأمان والخصوصية
قلل الانكشاف بحدود ثقة صريحة وجمع أدنى للبيانات وإدارة مفاتيح منصية مناسبة.
في هذه الصفحة
أهداف الدرس
- حدد نقاط الدخول غير الموثوقة واحمِ البيانات الحساسة.
- اشرح حدود العزل وKeystore وفحوص العميل.
سمّ الأصول والمستدعين
ابدأ بما يجب حمايته: رموز المصادقة وملاحظات القراءة الخاصة وهوية الحساب ومفاتيح التوقيع والعمليات المعلقة. ثم حدد المؤثرين في الإدخال: تطبيق آخر أو خدمة شبكة أو رابط عميق أو نسخة مستعادة أو مستخدم جهاز مشترك. يفيد عزل Android لكن المكونات المتاحة وURI الممنوح والسجلات والنسخ وطلبات الخادم تعبر حدوده. يجب أن يقود نموذج التهديد لضوابط واختبارات ملموسة. لا تعد بأن التمويه أو شاشة مخفية يجعل سراً مضمناً في APK سرياً.
تحقق وفوّض كل دخول خارجي
قد يحمل الرابط العميق معرّفاً صحيح الصياغة لسجل لا يحق للحساب الحالي الوصول إليه. يفحص التحقق الشكل ويفحص التفويض السلطة. نفذ كليهما في الطبقة المناسبة وافرض تفويض الخادم مستقلاً عن التطبيق. اسمح بمخططات ومضيفين متوقعين للروابط الخارجية بدلاً من قبول كل URI. استخدم معاملات الاستعلام وقيّد المكونات المتاحة وتجنب تمرير Intent غير موثوق بكامل أعلامه. يجب أن تقود الافتراضات الآمنة لرفض قابل للتعافي لا لمحاولة تفسير إدخال اعتباطي كأمر داخلي.
fun allowedBookLink(uri: Uri): String? {
if (uri.scheme != "https" || uri.host != "reading.example.com") return null
val parts = uri.pathSegments
if (parts.size != 2 || parts[0] != "books") return null
return parts[1].takeIf { it.matches(Regex("[A-Za-z0-9_-]{1,80}")) }
}
استورد android.net.Uri. النطاق reading.example.com مثال توثيقي وليس خدمة مضبوطة. يقبل المحلل عقد مسار صغيراً، ويظل المستودع والخلفية ملزمين بتفويض المعرّف. تحتاج App Links الموثقة إعداد ربط نطاق منفصلاً.
استخدم Keystore لمواد المفاتيح
يستطيع Android Keystore حفظ مواد مفاتيح غير قابلة للتصدير وتقييد العمليات. لا يجعل كل استخدام آمناً ويختلف الدعم العتادي بحسب الجهاز والإعداد. للتشفير المحلي الحساس اختر تصميماً مراجعاً بتشفير موثق وعالج إبطال المفتاح والتعافي. يولد المثال مفتاح AES على API 23 أو أعلى، ولا ينبغي للتوليد استبدال اسم قائم عابراً. ليس Keystore مكاناً لإخفاء سر خلفية رئيسي مشترك يُشحن لكل جهاز، ولا يعوض التشفير التحكم بالوصول أو سياسة نسخ مدروسة.
@RequiresApi(23)
fun generateNotesKey(alias: String): SecretKey {
val generator = KeyGenerator.getInstance(
KeyProperties.KEY_ALGORITHM_AES, "AndroidKeyStore"
)
generator.init(KeyGenParameterSpec.Builder(
alias, KeyProperties.PURPOSE_ENCRYPT or KeyProperties.PURPOSE_DECRYPT
).setBlockModes(KeyProperties.BLOCK_MODE_GCM)
.setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
.build())
return generator.generateKey()
}
استورد أصناف Android Keystore وRequiresApi من AndroidX وأنواع javax.crypto. احمِ الاستدعاء على الأجهزة المدعومة الأقدم. يجب أن يولد تصميم AES-GCM الكامل قيمة nonce جديدة لكل تشفير بالمفتاح نفسه ويحفظ nonce ووسم المصادقة ويعرّف التعافي من فقد المفتاح.
اجمع أقل واحتفظ بقصد
ينبغي ألا تظهر الملاحظات الخاصة افتراضياً في سجلات التشخيص أو خصائص التحليلات أو معاينات الإشعارات أو آثار التعطل. فضّل فئات أحداث ومعرّفات عمليات معتمة وحدد الاحتفاظ والحذف لكل مخزن. راجع قواعد النسخ ونقل الأجهزة كي لا تعود مواد حساسة إلى سياق غير صالح أو غير مقصود. ينبغي للخروج مسح حالة الحساب وإبطال العمليات المعلقة وفق السياسة لا استبدال الشاشة فقط. عامل جمع SDK الخارجي جزءاً من سلوك التطبيق واجعل الإفصاحات مطابقة لما ترسله الشيفرة فعلياً.
اختبر الرفض والتعافي
جرّب الروابط المشوهة ومعرّفات الحساب الآخر والاعتمادات المنتهية والمفاتيح المفقودة والأذونات المرفوضة والبيانات المستعادة القديمة. افحص manifest المدمج وإعداد شبكة الإصدار لا سلوك التنقيح فقط. تحتاج تحديثات الاعتماديات تحقق المصدر والتوافق؛ لا يثبت اسم مكتبة أمني ملاءمتها. أبقِ أسرار التوقيع خارج المستودع وقيّد الوصول في CI. يصف التحقق الأمني المفيد الأصل المحمي ومحاولة عبور الحد والرفض الملاحظ والتعافي المتاح للمستخدم المصرح.
الأخطاء الشائعة وإصلاحها
يُعامل فحص العميل كتفويض
- لماذا يحدث؟
- تثق الخلفية بمعرّف يرسله التطبيق.
- كيف تصلحه؟
- افرض ملكية الحساب في كل عملية خادم محمية.
- كيف تتجنب تكراره؟
- اختبر وصول الحسابات المتقاطعة مستقلاً عن ظهور الواجهة.
لا يتعافى التشفير بعد نقل الجهاز
- لماذا يحدث؟
- استعيدت ملفات مشفرة دون مفتاح صالح.
- كيف تصلحه؟
- حدد استثناءات نسخ مدعومة أو مسار تعاف موثقاً.
- كيف تتجنب تكراره؟
- اختبر الاستعادة وإبطال المفتاح قبل الإصدار.
تكشف السجلات عناوين خاصة أو رموزاً
- لماذا يحدث؟
- سُجلت طلبات أو كائنات مجال خام.
- كيف تصلحه؟
- أزل الحمولات الحساسة واستخدم أحداثاً منظمة محجوبة.
- كيف تتجنب تكراره؟
- راجع التسجيل بوصفه جمع بيانات.
اختبر فهمك
1. يقبل محلل رابط معرّف سجل صحيحاً. اشرح الفحصين التاليين قبل عرض ملاحظات خاصة.
اعرض الحل المشروح
أكد المصادقة الحالية وفوّض الحساب للسجل عبر عقد البيانات أو الخادم الموثوق. يثبت المسار الصحيح الصياغة فقط. عند غياب الوصول ارفض دون تسريب التفاصيل واعرض دخولاً أو تنقلاً مناسباً. لا تعتمد على زر مخفي لمنع الدخول المباشر.
2. يقترح تطبيق وضع سر API رئيسي في BuildConfig وتمويه الإصدار. قيّم الخطة.
اعرض الحل المشروح
يبقى السر مشحوناً لكل عميل ويمكن استخراجه أو استخدامه من تطبيق مخترق. أبقِ الأسرار المميزة في بنية موثوقة وأصدر اعتمادات محدودة قابلة للإبطال لعملاء مصادقين. قد يصعّب التمويه الهندسة العكسية لكنه لا ينشئ حد تخزين آمن لاعتماد خادم مشترك.
أهم ما تعلمته
- التحقق والتفويض والسرية ضوابط منفصلة.
- يحمي Keystore مواد المفاتيح ضمن نموذج تهديد محدد.
- تقليل البيانات وسياسة التعافي جزء من التصميم الأمني.