ملف تخزين مفاتيح مستنِد إلى الجهاز

يتيح توفُّر بيئة تنفيذ موثوق بها (TEE) في نظام على شريحة (SoC) لأجهزة Android تقديم خدمات أمان قوية مدعومة بالأجهزة، لنظام التشغيل Android وخدمات النظام الأساسي وحتى لتطبيقات الجهات الخارجية (في شكل إضافات خاصة بنظام Android لبنية تشفير لغة البرمجة Java العادية، يُرجى الاطّلاع على KeyGenParameterSpec).

مسرد المصطلحات

في ما يلي نظرة عامة سريعة على مكوّنات ملف تخزين المفاتيح والعلاقات بينها.

AndroidKeyStore
واجهة برمجة تطبيقات Android Framework والمكوّن الذي تستخدمه التطبيقات للوصول إلى وظائف ملف تخزين المفاتيح وهو تنفيذ لواجهات برمجة التطبيقات العادية لبنية تشفير لغة البرمجة Java، ولكنّه يضيف أيضًا إضافات خاصة بنظام Android ويتألف من رمز Java يتم تشغيله في مساحة عملية التطبيق الخاصة. AndroidKeyStore ينفّذ طلبات التطبيق لسلوك ملف تخزين المفاتيح من خلال إعادة توجيهها إلى برنامج ملف تخزين المفاتيح.
برنامج خفي لملف تخزين المفاتيح
برنامج خفي لنظام Android يتيح الوصول إلى جميع وظائف ملف تخزين المفاتيح من خلال واجهة برمجة تطبيقات Binder. هذا البرنامج الخفي مسؤول عن تخزين keyblobs التي تم إنشاؤها بواسطة تنفيذ KeyMint (أو Keymaster) الأساسي، والتي تحتوي على مادة المفتاح السري، مشفّرة حتى يتمكّن ملف تخزين المفاتيح من تخزينها ولكن لا يمكنه استخدامها أو الكشف عنها.
خدمة KeyMint HAL
خادم AIDL ينفّذ IKeyMintDevice HAL، ما يتيح الوصول إلى KeyMint TA الأساسي.
تطبيق KeyMint الموثوق به (TA)
برنامج يتم تشغيله في سياق آمن، غالبًا في TrustZone على شريحة ARM SoC، ويوفّر جميع عمليات التشفير الآمنة. يمكن لهذا التطبيق الوصول إلى مادة المفتاح الأولية، ويتحقّق من جميع شروط التحكّم في الوصول إلى المفاتيح قبل السماح باستخدامها.
LockSettingsService
مكوّن نظام Android المسؤول عن مصادقة المستخدم، سواء كانت كلمة المرور أو بصمة الإصبع وهو ليس جزءًا من ملف تخزين المفاتيح، ولكنّه ذو صلة لأنّ ملف تخزين المفاتيح يتيح مفهوم المفاتيح المرتبطة بالمصادقة: وهي المفاتيح التي لا يمكن استخدامها إلا إذا تمت مصادقة المستخدم. يتفاعل LockSettingsService مع Gatekeeper TA و Fingerprint TA للحصول على رموز المصادقة، والتي يقدّمها إلى برنامج ملف تخزين المفاتيح، ويستخدمها KeyMint TA.
Gatekeeper TA
المكوّن الذي يتم تشغيله في البيئة الآمنة والمسؤول عن مصادقة كلمات مرور المستخدمين وإنشاء رموز المصادقة المستخدَمة لإثبات أنّ KeyMint TA قد أجرى عملية مصادقة لمستخدم معيّن في وقت معيّن.
Fingerprint TA
المكوّن الذي يتم تشغيله في البيئة الآمنة والمسؤول عن مصادقة بصمات أصابع المستخدمين وإنشاء رموز المصادقة المستخدَمة لإثبات أنّ KeyMint TA قد أجرى عملية مصادقة لمستخدم معيّن في وقت معيّن.

هندسة معمارية

توفّر واجهة برمجة تطبيقات Android Keystore وKeyMint HAL الأساسي مجموعة أساسية ولكنها كافية من العناصر الأولية للتشفير للسماح بتنفيذ البروتوكولات باستخدام المفاتيح المدعومة بالأجهزة والتي يتم التحكّم في الوصول إليها.

إنّ KeyMint HAL هي خدمة يقدّمها المصنّع الأصلي للجهاز ويستخدمها ملف تخزين المفاتيح لتقديم خدمات التشفير المستنِدة إلى الأجهزة. للحفاظ على أمان مادة المفتاح الخاص، لا تنفّذ عمليات HAL أي عمليات حساسة في مساحة المستخدم، أو حتى في مساحة النواة. بدلاً من ذلك، يفوّض KeyMint HAL الذي يتم تشغيله في Android العمليات الحساسة إلى TA يتم تشغيله في نوع من البيئة الآمنة، عادةً عن طريق ترتيب الطلبات وإلغاء ترتيبها بتنسيق سلكي محدّد في التنفيذ.

تبدو الهندسة المعمارية الناتجة على النحو التالي:

الوصول إلى KeyMint

الشكل 1: الوصول إلى KeyMint

إنّ KeyMint HAL API منخفض المستوى، ويستخدمه مكوّنات النظام الأساسي الداخلية، ولا يتم عرضه على مطوّري التطبيقات. يتم وصف واجهة برمجة تطبيقات Java ذات المستوى الأعلى المتاحة للتطبيقات على موقع Android Developer.

التحكم في الدخول

يوفّر ملف تخزين مفاتيح Android مكوّنًا مركزيًا لتخزين واستخدام مفاتيح التشفير المدعومة بالأجهزة، لكل من التطبيقات ومكوّنات النظام الأخرى. على هذا النحو، يقتصر الوصول إلى أي مفتاح فردي عادةً على التطبيق أو مكوّن النظام الذي أنشأ المفتاح.

نطاقات ملف تخزين المفاتيح

لدعم التحكّم في الوصول هذا، يتم تعريف المفاتيح لملف تخزين المفاتيح باستخدام واصف المفتاح. يشير واصف المفتاح هذا إلى نطاق ينتمي إليه الواصف، بالإضافة إلى هوية داخل هذا النطاق.

تصل تطبيقات Android إلى ملف تخزين المفاتيح باستخدام بنية تشفير لغة البرمجة Java العادية، التي تحدّد المفاتيح باستخدام اسم مستعار على شكل سلسلة. تتم مطابقة طريقة التعريف هذه مع نطاق APP في ملف تخزين المفاتيح داخليًا، ويتم أيضًا تضمين رقم تعريف المستخدم الخاص بالمتصل لإزالة الغموض عن المفاتيح من تطبيقات مختلفة، ما يمنع أحد التطبيقات من الوصول إلى مفاتيح تطبيق آخر.

داخليًا، يتلقّى رمز الأُطر أيضًا رقم تعريف مفتاح رقميًا فريدًا بعد تحميل المفتاح. يُستخدم رقم التعريف الرقمي هذا كمعرّف لواصفات المفاتيح ضمن نطاق KEY_ID. ومع ذلك، لا يزال يتم التحكّم في الوصول: حتى إذا اكتشف أحد التطبيقات رقم تعريف مفتاح لمفتاح تطبيق آخر، لا يمكنه استخدامه في الظروف العادية.

ومع ذلك، من الممكن أن يمنح أحد التطبيقات تطبيقًا مختلفًا (كما هو محدّد بواسطة رقم تعريف المستخدم) إذن استخدام مفتاح. تُرجع عملية المنح هذه معرّف منح فريدًا، يُستخدم كمعرّف لواصفات المفاتيح ضمن نطاق GRANT. ومرة أخرى، لا يزال يتم التحكّم في الوصول: حتى إذا اكتشف تطبيق ثالث رقم تعريف المنح لمفتاح المستفيد، لا يمكنه استخدامه.

يتيح ملف تخزين المفاتيح أيضًا نطاقَين آخرَين لواصفات المفاتيح، ويتم استخدامهما لمكوّنات النظام الأخرى ولا يتوفّران للمفاتيح التي أنشأها التطبيق:

  • يشير النطاق BLOB إلى عدم توفُّر معرّف للمفتاح في واصف المفتاح، وبدلاً من ذلك، يحتوي واصف المفتاح على keyblob نفسه ويتعامل العميل مع تخزين keyblob. يتم استخدام هذا من قِبل العملاء (على سبيل المثال، vold) الذين يحتاجون إلى الوصول إلى ملف تخزين المفاتيح قبل تحميل قسم البيانات.
  • يسمح النطاق SELINUX لمكوّنات النظام بمشاركة المفاتيح، مع التحكّم في الوصول من خلال معرّف رقمي يتوافق مع تصنيف SELinux (يُرجى الاطّلاع على سياسة SELinux لـ keystore_key).

سياسة SELinux لـ keystore_key

يتم ضبط قيم المعرّفات المستخدَمة لواصفات المفاتيح Domain::SELINUX في ملف سياسة SELinux keystore2_key_context. يربط كل سطر في هذه الملفات رقمًا بتصنيف SELinux، على سبيل المثال:

# wifi_key is a keystore2_key namespace intended to be used by wpa supplicant and
# Settings to share Keystore keys.
102            u:object_r:wifi_key:s0

يجب أن يتضمّن المكوّن الذي يحتاج إلى الوصول إلى المفتاح الذي يحمل رقم التعريف 102 في نطاق SELINUX سياسة SELinux المقابلة. على سبيل المثال، للسماح لـ wpa_supplicant بالحصول على هذه المفاتيح واستخدامها، أضِف السطر التالي إلى hal_wifi_supplicant.te:

allow hal_wifi_supplicant wifi_key:keystore2_key { get, use };

يتم تقسيم المعرّفات الرقمية لمفاتيح Domain::SELINUX إلى نطاقات لدعم أقسام مختلفة بدون حدوث تعارضات:

القسم النطاق ملفات الإعداد
النظام 0 ... 9,999 /system/etc/selinux/keystore2_key_contexts, /plat_keystore2_key_contexts
النظام الموسَّع 10,000 ... 19,999 /system_ext/etc/selinux/system_ext_keystore2_key_contexts, /system_ext_keystore2_key_contexts
المنتج 20,000 ... 29,999 /product/etc/selinux/product_keystore2_key_contexts, /product_keystore2_key_contexts
المورّد 30,000 ... 39,999 /vendor/etc/selinux/vendor_keystore2_key_contexts, /vendor_keystore2_key_contexts

تم تحديد القيم المحدّدة التالية لقسم النظام:

الرقم التعريفي لمساحة الاسم تصنيف SEPolicy الرقم التعريفي الفريد الوصف
0 su_key لا ينطبق مفتاح المستخدم المتميّز يُستخدم لأغراض الاختبار فقط في إصدارات userdebug وeng. لا صلة له بإصدارات المستخدم.
1 shell_key لا ينطبق مساحة الاسم المتاحة للواجهة تُستخدم في الغالب للاختبار، ولكن يمكن استخدامها أيضًا في إصدارات المستخدم من سطر الأوامر.
100 vold_key لا ينطبق مخصّص للاستخدام من قِبل vold
101 odsign_key لا ينطبق يستخدمه برنامج التوقيع على الجهاز
102 wifi_key AID_WIFI(1010) يستخدمه نظام Wi-Fi الفرعي في Android، بما في ذلك wpa_supplicant
103 locksettings_key لا ينطبق يستخدمه LockSettingsService
120 resume_on_reboot_key AID_SYSTEM(1000) يستخدمه خادم نظام Android لدعم الاستئناف عند إعادة التشغيل

متجهات الوصول

يسمح ملف تخزين المفاتيح بالتحكّم في العمليات التي يمكن إجراؤها على مفتاح، بالإضافة إلى التحكّم في الوصول العام إلى مفتاح. يتم وصف keystore2_key الأذونات في الملف KeyPermission.aidl.

أذونات النظام

بالإضافة إلى عناصر التحكّم في الوصول لكل مفتاح الموضّحة في سياسة SELinux لـ keystore_key، يوضّح الجدول التالي أذونات SELinux الأخرى المطلوبة لإجراء عمليات النظام والصيانة المختلفة:

الإذن المعنى
add_auth مطلوب لإضافة رموز المصادقة إلى ملف تخزين المفاتيح، ويستخدمه موفّرو المصادقة مثل Gatekeeper أو BiometricManager
clear_ns مطلوب لحذف جميع المفاتيح في مساحة اسم معيّنة، ويُستخدم كعملية صيانة عند إلغاء تثبيت التطبيقات
list مطلوب من النظام لتعداد المفاتيح حسب خصائص مختلفة، مثل الملكية أو ما إذا كانت مرتبطة بالمصادقة لا يحتاج المتصلون إلى هذا الإذن عند تعداد مساحات الأسماء الخاصة بهم (التي يغطيها إذن get_info)
lock مطلوب لإعلام ملف تخزين المفاتيح بأنّه تم قفل الجهاز، ما يؤدي بدوره إلى إزالة المفاتيح المميّزة لضمان عدم توفُّر المفاتيح المرتبطة بالمصادقة
unlock مطلوب لإعلام ملف تخزين المفاتيح بأنّه تم فتح قفل الجهاز، ما يؤدي إلى استعادة إمكانية الوصول إلى المفاتيح المميّزة التي تحمي المفاتيح المرتبطة بالمصادقة
reset مطلوب لإعادة ضبط ملف تخزين المفاتيح على الإعدادات الأصلية، ما يؤدي إلى حذف جميع المفاتيح غير الضرورية لتشغيل نظام التشغيل Android

السجلّ

في Android 5 والإصدارات الأقدم، كان لدى Android واجهة برمجة تطبيقات بسيطة لخدمات التشفير المستنِدة إلى الأجهزة، والتي يقدّمها الإصداران 0.2 و0.3 من طبقة تجريد الأجهزة (HAL) في Keymaster. قدّم ملف تخزين المفاتيح عمليات التوقيع والتحقّق الرقمية، بالإضافة إلى إنشاء واستيراد أزواج مفاتيح التوقيع غير المتماثلة. تم تنفيذ ذلك بالفعل على العديد من الأجهزة، ولكن هناك العديد من الأهداف الأمنية التي لا يمكن تحقيقها بسهولة باستخدام واجهة برمجة تطبيقات التوقيع فقط. وسّع Android 6.0 واجهة برمجة تطبيقات ملف تخزين المفاتيح لتوفير مجموعة أوسع من الإمكانات.

Android 6.0

في Android 6.0، أضاف Keymaster 1.0 عناصر أولية للتشفير المتماثل، وهي AES وHMAC، ونظام تحكّم في الوصول للمفاتيح المدعومة بالأجهزة. يتم تحديد عناصر التحكّم في الوصول أثناء إنشاء المفتاح ويتم فرضها طوال فترة صلاحية المفتاح. يمكن حصر استخدام المفاتيح بعد مصادقة المستخدم فقط، ولأغراض محدّدة فقط أو باستخدام معلّمات تشفير محدّدة.

بالإضافة إلى توسيع نطاق العناصر الأولية للتشفير، أضاف ملف تخزين المفاتيح في Android 6.0 ما يلي:

  • مخطط للتحكّم في الاستخدام للسماح بحصر استخدام المفتاح، ما يقلّل من خطر تعريض الأمان للخطر بسبب إساءة استخدام المفاتيح
  • مخطط للتحكّم في الوصول لتمكين حصر المفاتيح على مستخدمين محدّدين، عملاء، ونطاق زمني محدّد

Android 7.0

في Android 7.0، أضاف Keymaster 2 إمكانية استخدام شهادة المفتاح وربط الإصدار.

توفر شهادة المفتاح شهادات مفتاح عام تحتوي على وصف تفصيلي للمفتاح وعناصر التحكم في الوصول إليه، وذلك لجعل إمكانية التحقق عن بعد من وجود المفتاح في أجهزة آمنة و إعداداته ممكنة.

ربط الإصدار يربط المفاتيح بإصدار نظام التشغيل وإصدار رمز التصحيح. يضمن ذلك ألا يتمكّن مهاجم يكتشف نقطة ضعف في إصدار قديم من النظام أو برنامج TEE من إعادة الجهاز إلى الإصدار المعرّض للخطر واستخدام المفاتيح التي تم إنشاؤها باستخدام الإصدار الأحدث. بالإضافة إلى ذلك، عند استخدام مفتاح بإصدار معيّن وإصدار رمز تصحيح معيّن على جهاز تمت ترقيته إلى إصدار أو رمز تصحيح أحدث، تتم ترقية المفتاح قبل أن يكون بالإمكان استخدامه، ويتم إبطال الإصدار السابق من المفتاح. أثناء ترقية الجهاز، يتم نقل المفاتيح للأمام مع الجهاز، ولكن أي إعادة للجهاز إلى إصدار سابق تؤدي إلى عدم إمكانية استخدام المفاتيح.

Android 8.0

في Android 8.0، انتقل Keymaster 3 من طبقة تجريد الأجهزة (HAL) القديمة التي تستخدم بنية C إلى واجهة C++ HAL التي تم إنشاؤها من تعريف بلغة تعريف واجهة الأجهزة الجديدة (HIDL). كجزء من التغيير، تغيّرت العديد من أنواع الوسيطات، على الرغم من أنّ الأنواع والطرق تتطابق مع الأنواع القديمة وطرق بنية HAL.

بالإضافة إلى مراجعة الواجهة هذه، وسّع Android 8.0 ميزة الشهادة في Keymaster 2 لتوفير شهادة رقم التعريف. توفّر شهادة رقم التعريف آلية محدودة واختيارية لإثبات صحة معرّفات الأجهزة بقوة، مثل الرقم التسلسلي للجهاز واسم المنتج ورقم تعريف الهاتف (IMEI أو MEID). لتنفيذ هذه الإضافة، غيّر Android 8.0 مخطط شهادة ASN.1 لإضافة شهادة رقم التعريف. تحتاج عمليات تنفيذ Keymaster إلى إيجاد طريقة آمنة لاسترداد عناصر البيانات ذات الصلة، بالإضافة إلى تحديد آلية لإيقاف الميزة بشكل آمن ودائم.

Android 9

في Android 9، تضمنت التحديثات ما يلي:

  • التحديث إلى Keymaster 4
  • إتاحة استخدام العناصر الآمنة المضمّنة
  • إتاحة استيراد المفاتيح الآمن
  • إتاحة التشفير باستخدام 3DES
  • إجراء تغييرات على ربط الإصدار بحيث يكون لـ boot.img وsystem.img إصدارات تم ضبطها بشكل منفصل للسماح بإجراء تحديثات مستقلة

Android 10

قدّم Android 10 الإصدار 4.1 من Keymaster HAL، الذي أضاف ما يلي:

  • إتاحة استخدام المفاتيح فقط عند فتح قفل الجهاز
  • إتاحة استخدام المفاتيح فقط في مراحل التشغيل المبكرة
  • إتاحة استخدام مفاتيح التخزين المغلّفة بالأجهزة بشكل اختياري لـ
  • إتاحة استخدام شهادة فريدة للجهاز بشكل اختياري في StrongBox

Android 12

قدّم Android 12 KeyMint HAL الجديد، الذي يحل محل Keymaster HAL ولكنّه يوفّر وظائف مماثلة. بالإضافة إلى جميع الميزات المذكورة أعلاه، يتضمّن KeyMint HAL أيضًا ما يلي:

  • إتاحة الاتفاق على مفتاح ECDH
  • إتاحة استخدام مفاتيح الشهادة التي يحدّدها المستخدم
  • إتاحة استخدام المفاتيح بعدد محدود من المرات

يتضمّن Android 12 أيضًا إصدارًا جديدًا من برنامج ملف تخزين المفاتيح، الذي تمت إعادة كتابته بلغة Rust ويُعرف باسم keystore2

Android 13

أضاف Android 13 الإصدار الثاني من KeyMint HAL، الذي يتيح استخدام Curve25519 لكل من التوقيع والاتفاق على المفتاح.