0Pricing
Swift Academy · درس

التحكم في الوصول إلى Keychain

قيّد الوصول إلى العناصر باستخدام المقاييس الحيوية وفتح الجهاز.

التحكم في الوصول إلى Keychain درس مجاني في Swift Academy على CoddyKit. هذا هو الدرس 2 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في Swift Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة Swift Academy 4 دروس في المجموع.

التحكم في وقت إمكانية قراءة الأسرار

لا يكفي تخزين السر وحده، بل يجب التحكم في وقت إمكانية قراءته. يوفّر Keychain فئات لإمكانية الوصول وعلامات للتحكم في الوصول، فتقيّد العناصر إلى أن يُلغى قفل الجهاز أو يُدخل رمز الدخول أو تُستخدم القياسات الحيوية. يحمي ذلك البيانات إذا فُقد الجهاز.

import Security
// Two layers of control:
//   kSecAttrAccessible  -> when readable (lock state)
//   SecAccessControl    -> user presence / biometrics

مفتاح kSecAttrAccessible

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

import Security
let query: [String: Any] = [
    kSecClass as String: kSecClassGenericPassword,
    kSecAttrAccount as String: "user",
    kSecValueData as String: Data("secret".utf8),
    kSecAttrAccessible as String:
        kSecAttrAccessibleWhenUnlocked
]
_ = query

WhenUnlocked

يجعل kSecAttrAccessibleWhenUnlocked العنصر قابلاً للقراءة فقط أثناء إلغاء قفل الجهاز. ولا تستطيع المهام التي تعمل في الخلفية أثناء القفل الوصول إليه. وهذا هو الخيار الافتراضي المناسب لمعظم رموز الجلسة.

import Security
// Readable only while unlocked; blocked when locked.
let level = kSecAttrAccessibleWhenUnlocked
_ = level

AfterFirstUnlock

يبقي kSecAttrAccessibleAfterFirstUnlock العنصر قابلاً للقراءة بعد أول إلغاء قفل عقب تشغيل الجهاز وحتى إعادة التشغيل التالية، حتى أثناء قفل الجهاز لاحقًا. استخدمه للأسرار التي تحتاج إليها عملية تعمل في الخلفية، مثل رمز معالجة الإشعارات الفورية.

import Security
// Available after the first unlock post-boot,
// including while subsequently locked.
let level = kSecAttrAccessibleAfterFirstUnlock
_ = level

متغيرات ThisDeviceOnly

لكل فئة من فئات إمكانية الوصول صيغة ...ThisDeviceOnly. وتُستبعد هذه العناصر من النسخ الاحتياطية المشفرة ولا تنتقل إلى جهاز جديد. استخدمها للمفاتيح التي يجب ألا تغادر هذه الأجهزة مطلقًا.

import Security
// Never backed up, never migrated:
let local = kSecAttrAccessibleWhenUnlockedThisDeviceOnly
_ = local

عند تعيين رمز الدخول

يخزّن kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly العنصر فقط إذا كان المستخدم قد عيّن رمز دخول، ويحذفه إذا أزال رمز الدخول. ويضمن ذلك أن يكون السر محميًا دائمًا برمز الدخول.

import Security
let level =
    kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly
// Item vanishes if the user disables their passcode.
_ = level

SecAccessControl لحضور المستخدم

بالإضافة إلى حالة القفل، ينشئ SecAccessControlCreateWithFlags سياسة تتطلب مصادقة المستخدم الفعلية، سواء بالقياسات الحيوية أو برمز الدخول، وقت القراءة. وتربطها عبر kSecAttrAccessControl بدلًا من مفتاح إمكانية الوصول أو معه.

import Security
func makeControl() -> SecAccessControl? {
    return SecAccessControlCreateWithFlags(
        nil,
        kSecAttrAccessibleWhenUnlockedThisDeviceOnly,
        .userPresence,
        nil)
}

علامات التحكم في الوصول

تحدد العلامات المتطلب بدقة أكبر: تتيح .userPresence استخدام القياسات الحيوية أو الرجوع إلى رمز الدخول؛ وتبطل .biometryCurrentSet صلاحية العنصر إذا تغيرت بصمات الأصابع أو الوجوه المسجلة؛ ويفرض .devicePasscode إدخال رمز الدخول. ادمج بينها للتعبير عن متطلبات الأمان لديك.

import Security
// .userPresence        -> biometric OR passcode
// .biometryAny         -> any enrolled biometric
// .biometryCurrentSet  -> invalidate on biometric change
// .devicePasscode      -> passcode only
let flags: SecAccessControlCreateFlags = [.userPresence]
_ = flags

إضافة عنصر محمي

لتخزين سر محمي بالقياسات الحيوية، ضع كائن SecAccessControl ضمن kSecAttrAccessControl. وستطلب أي قراءة لاحقة من المستخدم المصادقة قبل إرجاع البيانات.

import Security
func saveProtected(_ data: Data, account: String,
                   control: SecAccessControl) -> Bool {
    let query: [String: Any] = [
        kSecClass as String: kSecClassGenericPassword,
        kSecAttrAccount as String: account,
        kSecValueData as String: data,
        kSecAttrAccessControl as String: control]
    return SecItemAdd(query as CFDictionary, nil)
        == errSecSuccess
}

القراءة تطلب مصادقة المستخدم

تؤدي قراءة عنصر محمي إلى تشغيل واجهة المصادقة تلقائيًا. ويمكنك تقديم سلسلة توضح السبب عبر kSecUseOperationPrompt حتى يشرح الطلب سبب الحاجة إلى الوصول. وتتوقف القراءة إلى أن يصادق المستخدم أو يلغي العملية.

import Security
func readProtected(account: String) -> Data? {
    let query: [String: Any] = [
        kSecClass as String: kSecClassGenericPassword,
        kSecAttrAccount as String: account,
        kSecReturnData as String: true,
        kSecUseOperationPrompt as String:
            String(localized: "Unlock your saved key")]
    var out: CFTypeRef?
    return SecItemCopyMatching(query as CFDictionary,
        &out) == errSecSuccess ? out as? Data : nil
}

اختيار المستوى المناسب

طابق السياسة مع مستوى المخاطر:

  • رمز جلسة يُستخدم في الخلفية: AfterFirstUnlock.
  • رمز يُستخدم في واجهة المستخدم فقط: WhenUnlocked.
  • سر عالي القيمة: SecAccessControl مع .userPresence وفئة ThisDeviceOnly.

المستوى الأكثر تقييدًا أكثر أمانًا، لكنه يمنع الوصول في الخلفية؛ لذلك يجب تحقيق التوازن بين الأمرين.

import Security
// High-value: biometric-gated, device-bound, no backup
let control = SecAccessControlCreateWithFlags(
    nil,
    kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly,
    .userPresence, nil)
_ = control

اختبار سريع

تذكّر فئة إمكانية الوصول المناسبة لسر تحتاج إليه عملية تعمل في الخلفية.

مراجعة

لقد تعلمت تقييد الوصول إلى عناصر Keychain:

  • يضبط kSecAttrAccessible إتاحة العنصر وفق حالة القفل: WhenUnlocked وAfterFirstUnlock ومتغيرات ...ThisDeviceOnly التي تتجاوز النسخ الاحتياطية.
  • يربط WhenPasscodeSetThisDeviceOnly العنصر بوجود رمز دخول.
  • يتطلب SecAccessControl مع علامات مثل .userPresence أو .biometryCurrentSet المصادقة وقت القراءة.
  • اختر المستوى الأكثر تقييدًا الذي يتيح نمط الوصول المطلوب لديك.

الأسئلة الشائعة

هل درس «التحكم في الوصول إلى Keychain» مجاني؟

نعم — نص درس «التحكم في الوصول إلى Keychain» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة Swift Academy، انتقل إلى CoddyKit PRO. تتضمن دورة Swift Academy 4 دروس في المجموع.

ماذا ستتعلم في «التحكم في الوصول إلى Keychain»؟

قيّد الوصول إلى العناصر باستخدام المقاييس الحيوية وفتح الجهاز. تتمرن على Swift Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.

هل أحتاج إلى خبرة سابقة لأبدأ Swift Academy؟

لا تُشترط خبرة سابقة. Swift Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 2 من أصل 4.

كم من الوقت يستغرق درس «التحكم في الوصول إلى Keychain»؟

معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.

هل يمكنني كتابة وتشغيل أكواد في درس Swift Academy هذا؟

نعم. كل درس في Swift Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.

جميع الدروس في هذه الدورة

  1. تخزين الأسرار في Keychain
  2. التحكم في الوصول إلى Keychain
  3. المصادقة البيومترية
  4. حماية البيانات والتشفير
← العودة إلى Swift Academy