Keychain iOS-da: bu nima, arxitektura va sirlar bilan ishlash

Muallif: IT Sectr Nashr etilgan: 2026-04-04 O'qish vaqti: 9 daq

Keychain (Kalitlar zanjiri) — iOS-da parollar, kriptografik kalitlar, sertifikatlar va maxfiy eslatmalarni xavfsiz saqlash uchun moʻljallangan himoyalangan ombordir. Apple Security Documentation (2025) maʼlumotlariga koʻra, Keychain A7 chipli va undan yangi barcha qurilmalarda Secure Enclave orqali apparat shifrlashdan foydalanadi. iOS Keychain arxitekturasini tushunish har bir dasturchi uchun tokenlar va dastur sirlarini toʻgʻri saqlash uchun zarurdir.

Asosiy

  • iOS Keychain — Secure Enclave orqali apparat himoyasi bilan sirlarni saqlash uchun shifrlangan SQLite maʼlumotlar bazasi.
  • Protection Class maʼlumotlar qachon mavjudligini aniqlaydi: qurilma qulfi ochiqda, birinchi ochishdan keyin yoki har doim.
  • Access Control List (ACL) — biometrik autentifikatsiyani ham oʻz ichiga olgan holda Keychain elementlariga kirishni cheklash mexanizmi.
  • SecItemAdd va SecItemCopyMatching — elementlarni yozish va oʻqish uchun Security framework-ning asosiy API-lari.
  • kSecAttrSynchronizable — foydalanuvchining barcha qurilmalarida kirish uchun Keychain-ni iCloud orqali sinxronlashga ruxsat beruvchi bayroq.

iOS-da Keychain nima?

iOS Keychain — Apple operatsion tizimiga oʻrnatilgan maxfiy maʼlumotlarni himoyalangan saqlash mexanizmi. UserDefaults yoki oddiy fayllardan farqli oʻlaroq, Keychain barcha elementlarni apparat darajasida shifrlaydi va xavfsizlik siyosatlariga asoslangan nozik kirish nazoratini taʻminlaydi.

Keychain iOS 2.0 da taqdim etilgan va shundan beri sezilarli oʻzgarishlarga uchradi: iOS 7 da Secure Enclave orqali apparat kalitlari qoʻllab-quvvatlandi, iOS 9 da Access Groups orqali ilovalar oʻrtasida Keychain boʻlimi qoʻshildi, iOS 13 da LAContext orqali biometrik bogʻlash qoʻllab-quvvatlandi. Apple WWDC Session (2024) maʼlumotlariga koʻra, App Store top 100 dagi iOS ilovalarining 90% dan ortigʻi autentifikatsiya tokenlarini saqlash uchun Keychain-dan foydalanadi.

Arxitektura nuqtai nazaridan, Keychain ilova sandboxidan tashqarida joylashgan shifrlangan SQLite maʼlumotlar bazasidir. Har bir element (SecItem) alohida kalit bilan shifrlanadi, bu kalit esa oʻz navbatida Secure Enclave apparat kaliti bilan himoyalanadi. Tizim xizmati Securityd ilovaning huquqlari (entitlements) va soʻralgan himoya sinfiga asoslanib Keychain-ga kirishni boshqaradi.

Keychain-ning boshqa saqlash usullariga nisbatan muhim afzalligi: maʼlumotlar avtomatik ravishda OT tomonidan shifrlanadi va deshifrlanadi. Dasturchi kriptografiyani qoʻlda amalga oshirishi shart emas — toʻgʻri parametrlar bilan SecItemAdd-ni chaqirish kifoya. iOS, Access Groups toʻgʻri sozlanganida, Keychain maʼlumotlarini boshqa ilovalar oʻqiy olmasligini kafolatlaydi.

Keychain arxitekturasi

Keychain arxitekturasi bir necha darajalarni oʻz ichiga oladi: fizik (Secure Enclave), tizim (Security.framework), amaliy (API SecItem*) va mantiqiy (Access Groups, Protection Classes). Har bir darajani tushunish sirlarni saqlashni toʻgʻri loyihalashga yordam beradi.

SecItemAdd va SecItemCopyMatching

Keychain bilan ishlash uchun asosiy API Security framework funksiyalaridir: qoʻshish uchun SecItemAdd, oʻqish uchun SecItemCopyMatching, yangilash uchun SecItemUpdate va oʻchirish uchun SecItemDelete. Har bir funksiya qidirilayotgan yoki saqlanayotgan elementning atributlarini tavsiflovchi query lugʻatini qabul qiladi.

Query-ning asosiy atributlari: kSecClass — element turi (kSecClassGenericPassword, kSecClassKey, kSecClassCertificate), kSecAttrAccount — sinf ichidagi noyob identifikator, kSecValueData — saqlanadigan maʼlumotlar (Data), kSecAttrAccessible — himoya sinfi. SecItemCopyMatching kSecReturnData bayrogʻi bilan element maʼlumotlarini, kSecMatchLimit bilan esa natijalar sonini qaytaradi.

Muhim: barcha funksiyalar OSStatus holatini qaytaradi. Muvaffaqiyatli operatsiya errSecSuccess (0) qaytaradi. Xatolar: errSecItemNotFound (-25300) — element topilmadi, errSecDuplicateItem (-25299) — element allaqachon mavjud, errSecAuthFailed (-25293) — biometrik autentifikatsiya muvaffaqiyatsiz tugadi. Dasturchi har bir holatni toʻgʻri boshqarishi kerak.

Himoya sinflari (Protection Class)

Protection Class — kSecAttrAccessible atributi boʻlib, Keychain-dagi maʼlumotlar qachon oʻqish uchun mavjudligini aniqlaydi. iOS turli darajadagi mavjudlik va xavfsizlikka ega olti himoya sinfini qoʻllab-quvvatlaydi.

Aksariyat stsenariylar uchun tavsiya etilgan sinf kSecAttrAccessibleWhenUnlockedThisDeviceOnly: maʼlumotlar faqat qurilma qulfi ochiqda mavjud va iCloud Backup-ga nusxalanmaydi. Qayta yuklashdan keyin mavjud boʻlishi kerak boʻlgan (lekin faqat birinchi ochishdan keyin) maʼlumotlar uchun kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly dan foydalaning. Har bir kirishda biometrik autentifikatsiya talab qiladigan muhim maʼlumotlar uchun kSecAttrAccessibleWhenUnlockedThisDeviceOnly-ni biometriya talab qiladigan ACL bilan birlashtiring.

ThisDeviceOnly qoʻshimchasiz sinflar (kSecAttrAccessibleWhenUnlocked, kSecAttrAccessibleAfterFirstUnlock) iCloud Backup-ga nusxalashga ruxsat beradi. Bu foydalanuvchi uchun qulay, ammo xavfsizlikni pasaytiradi — maʼlumotlar zaxiradan tiklanishi mumkin. Autentifikatsiya tokenlari uchun har doim ThisDeviceOnly dan foydalaning.

Access Control Lists (ACL)

Access Control List (ACL) — foydalanuvchi autentifikatsiyasiga asoslanib Keychain elementi bilan operatsiyalarni cheklaydigan mexanizm. ACL SecAccessControlCreateWithFlags orqali yaratiladi va elementni saqlashda kSecAttrAccessControl atributiga uzatiladi.

Qoʻllab-quvvatlanadigan bayroqlar: kSecAccessControlUserPresence — har qanday autentifikatsiya (Face ID, Touch ID yoki parol kodi), kSecAccessControlBiometryCurrentSet — faqat biometriya (hozirda roʻyxatdan oʻtgan barmoq izlari yoki yuz), kSecAccessControlDevicePasscode — faqat parol kodi. ACL har bir operatsiyaga qoʻllaniladi: elementni oʻqish, yangilash va oʻchirish ham autentifikatsiyani talab qiladi.

iOS 15+ da kSecAccessControlWatch bayrogʻi qoʻshildi — Apple Watch uchun, juftlashtirilgan soat orqali autentifikatsiyaga ruxsat beradi. ACL birlashtirilishi mumkin: masalan, kSecAccessControlUserPresence yoki kSecAccessControlBiometryAny ixtiyoriy parol kodi bilan (.or orientatsiyasi).

Keychain-dagi maʼlumot turlari

iOS Keychain toʻrtta asosiy element sinfini (kSecClass) qoʻllab-quvvatlaydi, har biri oʻz maʼlumot turi uchun moʻljallangan. Sinfni toʻgʻri tanlash elementlarni tashkil qilish va qidirishni soddalashtiradi.

kSecClassGenericPassword — umumiy parol: eng koʻp ishlatiladigan sinf. Noyob kalit bilan (kSecAttrAccount) ixtiyoriy ikkilik maʼlumotlarni (Data) saqlaydi. Tokenlar, API kalitlari, PIN-kodlar uchun mos keladi. Foydalanish uchun qoʻshimcha huquqlar (entitlements) talab qilmaydi.

kSecClassInternetPassword — internet paroli: tarmoq resursi bilan bogʼliq maʼlumotlarni saqlaydi. Qoʻshimcha atributlar: kSecAttrServer (server domeni), kSecAttrProtocol (https, ftp), kSecAttrPort, kSecAttrAuthenticationType. iOS AutoFill orqali bunday parollarni avtomatik toʻldirishi mumkin.

kSecClassKey — kriptografik kalit: shifrlash kalitlarini (AES, RSA, EC) saqlash uchun. Kalit Data sifatida emas, SecKeyRef sifatida saqlanadi. kSecClassCertificate — raqamli sertifikatlarni saqlash va tekshirish uchun X.509 sertifikati. Ikkala sinf kriptografik operatsiyalarni tushunishni va atributlarni toʻgʻri sozlashni talab qiladi.

Amalda, mobil ilovalarda Keychain dan foydalanishning %95 hollari autentifikatsiya tokenlarini saqlash uchun kSecClassGenericPassword va shaxsiy shifrlash kalitlarini saqlash uchun kSecClassKey bilan qoplanadi. kSecClassCertificate kamdan-kam qoʻllaniladi — odatda oʻz PKI-ga ega korporativ ilovalarda.

Kod namunalari: Swift-da Keychain bilan ishlash

Security framework-dan foydalangan holda Swift-da Keychain bilan ishlashning amaliy misollarini koʻrib chiqamiz. Har bir misol xatolarni boshqarish va Protection Class-ni toʻgʻri sozlashni oʻz ichiga oladi.

Tokenni saqlash va oʻqish

Asosiy misol autentifikatsiya tokenini WhenUnlockedThisDeviceOnly himoyasi bilan Keychain-da saqlaydi. Kalit (kSecAttrAccount) xizmat identifikatori, maʼlumotlar (kSecValueData) Data formatidagi tokendir.

swift
import Security

enum KeychainError: Error {
    case unexpectedStatus(OSStatus)
}

func saveToken(token: String, service: String) throws {
    let data = Data(token.utf8)
    let query: [String: Any] = [
        kSecClass as String: kSecClassGenericPassword,
        kSecAttrService as String: service,
        kSecAttrAccount as String: "auth_token",
        kSecValueData as String: data,
        kSecAttrAccessible as String:
            kSecAttrAccessibleWhenUnlockedThisDeviceOnly
    ]
    SecItemDelete(query as CFDictionary)
    let status = SecItemAdd(query as CFDictionary, nil)
    guard status == errSecSuccess else {
        throw KeychainError.unexpectedStatus(status)
    }
}

func readToken(service: String) throws -> String {
    let query: [String: Any] = [
        kSecClass as String: kSecClassGenericPassword,
        kSecAttrService as String: service,
        kSecAttrAccount as String: "auth_token",
        kSecReturnData as String: true,
        kSecMatchLimit as String: kSecMatchLimitOne
    ]
    var result: AnyObject?
    let status = SecItemCopyMatching(
        query as CFDictionary, &result
    )
    guard status == errSecSuccess,
        let data = result as? Data else {
        throw KeychainError.unexpectedStatus(status)
    }
    return String(decoding: data, as: UTF8.self)
}

Biometrik bogʻlash bilan saqlash

Misol kalitni biometriyaga bogʻlash uchun SecAccessControlCreateWithFlags dan foydalanishni koʻrsatadi. Elementga har bir kirish Face ID yoki Touch ID talab qiladi.

swift
import LocalAuthentication

func saveWithBiometry(data: Data, key: String) throws {
    let accessControl = SecAccessControlCreateWithFlags(
        nil,
        kSecAttrAccessibleWhenUnlockedThisDeviceOnly,
        .biometryCurrentSet,
        nil
    )

    let query: [String: Any] = [
        kSecClass as String: kSecClassGenericPassword,
        kSecAttrAccount as String: key,
        kSecValueData as String: data,
        kSecAttrAccessControl as String: accessControl as Any
    ]

    SecItemDelete(query as CFDictionary)
    let status = SecItemAdd(query as CFDictionary, nil)
    guard status == errSecSuccess else {
        throw KeychainError.unexpectedStatus(status)
    }
}

Ilovalar oʻrtasida Keychain Sharing

Misol bir dasturchining ilovalari oʻrtasida Keychain-ga umumiy kirish uchun Access Group sozlashni koʻrsatadi. keychain-access-groups entitlement talab qiladi.

swift
// Capabilities: Keychain Sharing yoqilgan
// App IDs: group.com.example.shared

func saveSharedToken(token: Data) {
    let query: [String: Any] = [
        kSecClass as String: kSecClassGenericPassword,
        kSecAttrAccount as String: "shared_token",
        kSecValueData as String: token,
        kSecAttrAccessGroup as String:
            "group.com.example.shared",
        kSecAttrAccessible as String:
            kSecAttrAccessibleWhenUnlockedThisDeviceOnly
    ]
    SecItemAdd(query as CFDictionary, nil)
}

Keychain bilan ishlashning eng yaxshi amaliyotlari

iOS Keychain dan toʻgʻri foydalanish odatdagi zaifliklar va maʼlumot yoʻqotilishining oldini oladigan bir necha asosiy qoidalarga rioya qilishni talab qiladi.

Barcha autentifikatsiya sirlari uchun ThisDeviceOnly dan foydalaning: kSecAttrAccessibleWhenUnlockedThisDeviceOnly tokenlarning iCloud Backup-ga tushmasligini kafolatlaydi. Agar tajovuzkor zaxiraga kirish imkoniyatiga ega boʻlsa, bu bayroqli Keychain maʼlumotlari mavjud boʻlmaydi. Istisno — foydalanuvchining barcha qurilmalarida mavjud boʻlishi kerak boʻlgan maʼlumotlar (masalan, oʻz xizmatlari uchun shifrlash kalitlari), ular uchun kSecAttrAccessibleWhenUnlocked-ni kSecAttrSynchronizable bilan ishlating.

Xom parollarni saqlamang — heshlar yoki sessiya tokenlarini saqlang. Apple Security Guide (2025) foydalanuvchi parolini Keychain-da ochiq matnda saqlashni hech qachon tavsiya etmaydi. Buning oʻrniga, OAuth 2.0 orqali muvaffaqiyatli autentifikatsiyadan keyin serverdan olingan refresh token-ni saqlang. Parol faqat tokenni olish uchun ishlatiladi va darhol xotiradan oʻchiriladi.

Keychain xatolarini toʻgʻri boshqaring: Keychain bilan har bir operatsiya tekshirilishi kerak boʻlgan OSStatus qaytaradi. Ayniqsa eʻtibor bering: errSecItemNotFound (token muddati tugagan yoki oʻchirilgan) va errSecAuthFailed (biometriya muvaffaqiyatsiz). Birinchi holatda ilova yangi autentifikatsiyani soʻrashi kerak, ikkinchisida — foydalanuvchiga muqobil usulni koʻrsatishi kerak (parol kodi). Hech qachon errSecItemNotFound holatini eʻtiborsiz qoldirmang — bu nil ni oʻqishga urinishda ilovaning ishdan chiqishiga olib keladi.

Keychain-ni haqiqiy qurilmada sinab koʻring: simulyatorda Secure Enclave yoʻq va biometrik ACL-larni qoʻllab-quvvatlamaydi. Har doim stsenariylarni tekshiring: birinchi ishga tushirish, zaxiradan tiklash, qurilma parolini oʻzgartirish, ilovani oʻchirish va qayta oʻrnatish. Haqiqiy qurilmada Keychain ilova oʻchirilgandan keyin saqlanadi, faqat kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly bayrogʻi ishlatilmagan boʻlsa — bu bayroq parol kodi olib tashlanganda tozalanadi.

Keychain operatsiyalari sonini minimallashtiring: har bir oʻqish yoki yozish operatsiyasi oqimni bloklashi mumkin boʻlgan Securityd tizim xizmatiga murojaatdir. Oʻqilgan tokenlarni sessiya davomida xotirada keshlang va Keychain-ga faqat ilova qayta ishga tushirilganda yoki autentifikatsiya xatosi (serverdan 401) boʻlganda qayta murojaat qiling. iOS qurilma qulflanganda Keychain-ni avtomatik bloklaydi, shuning uchun LAContext orqali biometriya soʻrovi bilan oʻqishni rejalashtiring.

Koʻp beriladigan savollar

Keychain-da maʼlumotlarni saqlash va qayta yuklashdan keyin oʻqish mumkinmi?

Ha, kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly yoki kSecAttrAccessibleAfterFirstUnlock himoya sinfidan foydalaning. Maʼlumotlar qayta yuklashdan keyin qurilmaning birinchi ochilishidan soʻng mavjud boʻladi. Ilova ishga tushirilganda avtomatik kirish uchun (ochishni kutmasdan) kSecAttrAccessibleAlways dan foydalaning, ammo bu xavfsizlikni pasaytiradi.

Foydalanuvchi chiqib ketganda Keychain-ni qanday tozalash mumkin?

Har bir maʼlumot turi uchun kSecClass ni oʻz ichiga olgan query bilan SecItemDelete-ni chaqiring. Ilovaning barcha elementlarini toʻliq tozalash uchun: SecItemDelete([kSecClass as String: kSecClassGenericPassword] as CFDictionary). kSecClassKey, kSecClassCertificate va kSecClassInternetPassword uchun takrorlang.

kSecAttrAccessible va kSecAttrAccessControl oʻrtasidagi farq nima?

kSecAttrAccessible maʼlumotlar qachon mavjudligini aniqlaydi (ochishda, birinchi ochishdan keyin va h.k.). kSecAttrAccessControl kim kirishi mumkinligini aniqlaydi (biometriya, parol kodi, har qanday autentifikatsiya). Ular birlashtiriladi: avval Protection Class, keyin ACL. Masalan, maʼlumotlar faqat ochishda VA faqat Face ID dan keyin mavjud.

Nima uchun SecItemCopyMatching errSecItemNotFound qaytaradi?

Sabablar: element hech qachon saqlanmagan, element parol kodi olib tashlanganda tozalangan (kSecAttrAccessibleWhenPasscodeSet ishlatilgan boʻlsa), ilova qayta oʻrnatilgan (Keychain saqlanadi, lekin yangi qurilmada zaxiradan tiklanmaydi), Access Group yoki dasturchi jamoasi identifikatori oʻzgargan. kSecAttrService va kSecAttrAccount-ni tekshiring.

Qurilma Keychain-da biometriyani qoʻllab-quvvatlashini qanday tekshirish mumkin?

LocalAuthentication-dan LAContext dan foydalaning: context.canEvaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, error: nil) ni chaqiring. Agar true qaytarsa — qurilma Touch ID yoki Face ID ni qoʻllab-quvvatlaydi. Keychain ACL uchun biometryCurrentSet (faqat joriy biometrik maʼlumotlar) yoki biometryAny (avval roʻyxatdan oʻtgan har qanday) bayrogʻidan foydalaning.

Xulosa

  • iOS Keychain — Secure Enclave orqali shifrlash va ACL orqali kirish nazorati bilan sirlarning apparat himoyalangan ombori.
  • Security framework elementlar bilan ishlash uchun SecItemAdd, SecItemCopyMatching, SecItemUpdate va SecItemDelete funksiyalarini taqdim etadi.
  • Protection Class (kSecAttrAccessible) stsenariy asosida tanlanadi: WhenUnlockedThisDeviceOnly — tokenlar uchun standart.
  • Biometrik ACL (kSecAttrAccessControl) har bir oʻqish operatsiyasi uchun Face ID yoki Touch ID talabini qoʻshadi.
  • kSecClassGenericPassword 95% hollarni qamrab oladi — tokenlar, API kalitlari, PIN-kodlar va eslatmalarni saqlash.
  • ThisDeviceOnly sirlarning iCloud Backup-ga nusxalanishini oldini oladi — autentifikatsiya tokenlari uchun majburiy.
  • OSStatus-ni toʻgʻri boshqarish va haqiqiy qurilmada sinov — Keychain bilan ishonchli ishlash uchun majburiy amaliyotlar.

Biz kalit topshirig'i bilan mobil ilovani ishlab chiqamiz

IT Sectr 2017-yildan beri startaplar va korxonalar uchun iOS va Android ilovalarini yaratadi. Biz sizga maslahat beramiz va eng yaxshi yechimni taklif qilamiz.

Loyihani muhokama qilish

Shuningdek o'qing