Keychain sa iOS: ano ito, arkitektura at paggawa gamit ang mga lihim

May-akda: IT Sectr Nai-publish: 2026-04-04 Oras ng pagbabasa: 9 min

Keychain (Sinturon ng mga Susi) — isang secure na imbakan sa iOS na idinisenyo para sa ligtas na pag-iimbak ng mga password, cryptographic key, sertipiko at kumpidensyal na mga tala. Ayon sa Apple Security Documentation (2025), ang Keychain ay gumagamit ng hardware encryption sa pamamagitan ng Secure Enclave sa lahat ng device na may A7 chip at mas bago. Ang pag-unawa sa arkitektura ng iOS Keychain ay kinakailangan para sa bawat developer upang maayos na maiimbak ang mga token at lihim ng aplikasyon.

Mga Pangunahin

  • iOS Keychain — naka-encrypt na SQLite database para sa pag-iimbak ng mga lihim na may proteksyon ng hardware sa pamamagitan ng Secure Enclave.
  • Protection Class ay tumutukoy kung kailan available ang data: kapag naka-unlock ang device, pagkatapos ng unang pag-unlock o palagi.
  • Access Control List (ACL) — mekanismo ng paghihigpit sa pag-access sa mga elemento ng Keychain, kasama ang biometric authentication.
  • SecItemAdd at SecItemCopyMatching — pangunahing API ng Security framework para sa pagsulat at pagbasa ng mga elemento.
  • kSecAttrSynchronizable — flag na nagpapahintulot sa pag-sync ng Keychain sa pamamagitan ng iCloud para sa pag-access sa lahat ng device ng user.

Ano ang Keychain sa iOS?

iOS Keychain — isang ligtas na mekanismo ng pag-iimbak para sa kumpidensyal na data, na naka-embed sa operating system ng Apple. Hindi tulad ng UserDefaults o ordinaryong file, ang Keychain ay nag-e-encrypt ng lahat ng elemento sa antas ng hardware at nagbibigay ng pinong kontrol sa pag-access batay sa mga patakaran sa seguridad.

Ang Keychain ay ipinakilala sa iOS 2.0 at mula noon ay sumailalim sa makabuluhang pagbabago: sa iOS 7 ay idinagdag ang suporta para sa hardware key sa pamamagitan ng Secure Enclave, sa iOS 9 — paghahati ng Keychain sa pagitan ng mga app sa pamamagitan ng Access Groups, sa iOS 13 — suporta para sa biometric binding sa pamamagitan ng LAContext. Ayon sa Apple WWDC Session (2024), higit sa 90% ng mga iOS app sa top 100 ng App Store ay gumagamit ng Keychain para sa pag-iimbak ng mga authentication token.

Sa arkitektura, ang Keychain ay isang naka-encrypt na SQLite database na matatagpuan sa labas ng sandbox ng app. Ang bawat elemento (SecItem) ay naka-encrypt na may hiwalay na key, na protektado ng hardware key ng Secure Enclave. Ang serbisyo ng system na Securityd ay namamahala sa pag-access sa Keychain batay sa mga karapatan ng app (entitlements) at hinihiling na klase ng proteksyon.

Isang mahalagang bentahe ng Keychain kumpara sa iba pang paraan ng pag-iimbak: ang data ay awtomatikong naka-encrypt at na-decrypt ng OS. Ang developer ay hindi kailangang magpatupad ng cryptography nang manu-mano — sapat na ang tumawag sa SecItemAdd na may tamang mga parameter. Ginagarantiyahan ng iOS na ang data mula sa Keychain ay hindi mababasa ng ibang mga app (na may tamang configuration ng Access Groups).

Arkitektura ng Keychain

Ang arkitektura ng Keychain ay may kasamang ilang antas: pisikal (Secure Enclave), system (Security.framework), application (API SecItem*) at lohikal (Access Groups, Protection Classes). Ang pag-unawa sa bawat antas ay tumutulong sa tamang pagdisenyo ng pag-iimbak ng mga lihim.

SecItemAdd at SecItemCopyMatching

Ang pangunahing API para sa paggawa gamit ang Keychain ay ang mga function ng Security framework: SecItemAdd para sa pagdaragdag, SecItemCopyMatching para sa pagbasa, SecItemUpdate para sa pag-update at SecItemDelete para sa pagtanggal. Bawat function ay tumatanggap ng query dictionary na naglalarawan ng mga attribute ng hinahanap o iniimbak na elemento.

Mga pangunahing attribute ng query: kSecClass — uri ng elemento (kSecClassGenericPassword, kSecClassKey, kSecClassCertificate), kSecAttrAccount — natatanging identifier sa loob ng klase, kSecValueData — iniimbak na data (Data), kSecAttrAccessible — klase ng proteksyon. SecItemCopyMatching na may flag na kSecReturnData ay nagbabalik ng data ng elemento, na may kSecMatchLimit — bilang ng mga resulta.

Mahalaga: lahat ng function ay nagbabalik ng OSStatus. Ang matagumpay na operasyon ay nagbabalik ng errSecSuccess (0). Mga error: errSecItemNotFound (-25300) — hindi natagpuan ang elemento, errSecDuplicateItem (-25299) — elemento ay umiiral na, errSecAuthFailed (-25293) — biometric authentication ay nabigo. Dapat na maayos na pangasiwaan ng developer ang bawat status.

Mga Klase ng Proteksyon (Protection Class)

Protection Class — attribute na kSecAttrAccessible, na tumutukoy kung kailan available ang data sa Keychain para sa pagbasa. Ang iOS ay sumusuporta sa anim na klase ng proteksyon na may iba't ibang antas ng availability at seguridad.

Ang inirerekomendang klase para sa karamihan ng mga scenario ay kSecAttrAccessibleWhenUnlockedThisDeviceOnly: ang data ay available lamang kapag naka-unlock ang device at hindi kinokopya sa iCloud Backup. Para sa data na dapat ay available pagkatapos ng restart (ngunit pagkatapos lamang ng unang pag-unlock), gamitin ang kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly. Para sa kritikal na data na nangangailangan ng biometric authentication sa bawat pag-access, pagsamahin ang kSecAttrAccessibleWhenUnlockedThisDeviceOnly sa ACL na nangangailangan ng biometry.

Ang mga klase na walang suffix na ThisDeviceOnly (kSecAttrAccessibleWhenUnlocked, kSecAttrAccessibleAfterFirstUnlock) ay nagpapahintulot ng pagkopya sa iCloud Backup. Ito ay maginhawa para sa user, ngunit binabawasan ang seguridad — ang data ay maaaring maibalik mula sa backup. Para sa mga authentication token, laging gamitin ang ThisDeviceOnly.

Access Control Lists (ACL)

Access Control List (ACL) — mekanismo na naghihigpit sa mga operasyon sa Keychain element batay sa authentication ng user. Ang ACL ay itinatakda sa pamamagitan ng SecAccessControlCreateWithFlags at ipinapasa sa attribute na kSecAttrAccessControl kapag nag-iimbak ng elemento.

Mga sinusuportahang flag: kSecAccessControlUserPresence — anumang authentication (Face ID, Touch ID o passcode), kSecAccessControlBiometryCurrentSet — biometry lamang (kasalukuyang rehistradong fingerprint o mukha), kSecAccessControlDevicePasscode — passcode lamang. Ang ACL ay inilalapat sa bawat operasyon: pagbasa, pag-update at pagtanggal ng elemento ay nangangailangan din ng authentication.

Sa iOS 15+ ay lumitaw ang flag na kSecAccessControlWatch — para sa Apple Watch, na nagpapahintulot ng authentication sa pamamagitan ng naka-pair na relo. Ang ACL ay maaaring pagsamahin: halimbawa, kSecAccessControlUserPresence o kSecAccessControlBiometryAny na may opsyonal na passcode (.or orientation).

Mga uri ng data sa Keychain

iOS Keychain ay sumusuporta sa apat na pangunahing klase ng elemento (kSecClass), bawat isa ay para sa sarili nitong uri ng data. Ang tamang pagpili ng klase ay nagpapasimple sa organisasyon at paghahanap ng mga elemento.

kSecClassGenericPassword — pangkalahatang password: ang pinakamadalas na ginagamit na klase. Nag-iimbak ng anumang binary data (Data) na may natatanging key (kSecAttrAccount). Angkop para sa mga token, API key, PIN code. Hindi nangangailangan ng karagdagang entitlements para magamit.

kSecClassInternetPassword — password sa internet: nag-iimbak ng data na nauugnay sa network resource. Mga karagdagang attribute: kSecAttrServer (domain ng server), kSecAttrProtocol (https, ftp), kSecAttrPort, kSecAttrAuthenticationType. Maaaring awtomatikong punan ng iOS ang mga naturang password sa pamamagitan ng AutoFill.

kSecClassKey — cryptographic key: para sa pag-iimbak ng mga encryption key (AES, RSA, EC). Ang key ay iniimbak bilang SecKeyRef, hindi bilang Data. kSecClassCertificate — X.509 certificate para sa pag-iimbak at pag-verify ng mga digital certificate. Ang parehong klase ay nangangailangan ng pag-unawa sa cryptographic operations at tamang configuration ng mga attribute.

Sa praktika, 95% ng mga kaso ng paggamit ng Keychain sa mga mobile app ay sakop ng kSecClassGenericPassword para sa pag-iimbak ng authentication token at kSecClassKey para sa pag-iimbak ng pribadong encryption key. Ang kSecClassCertificate ay bihirang gamitin — karaniwan sa mga corporate app na may sariling PKI.

Mga halimbawa ng code: paggawa gamit ang Keychain sa Swift

Tingnan natin ang mga praktikal na halimbawa ng paggawa gamit ang Keychain sa Swift gamit ang Security framework. Bawat halimbawa ay may kasamang paghawak ng error at tamang configuration ng Protection Class.

Pag-iimbak at pagbasa ng token

Ang pangunahing halimbawa ay nag-iimbak ng authentication token sa Keychain na may proteksyong WhenUnlockedThisDeviceOnly. Ang key (kSecAttrAccount) ay identifier ng serbisyo, ang data (kSecValueData) ay token sa Data format.

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)
}

Pag-iimbak na may biometric binding

Ang halimbawa ay nagpapakita ng paggamit ng SecAccessControlCreateWithFlags para i-bind ang key sa biometry. Bawat pag-access sa elemento ay mangangailangan ng Face ID o Touch ID.

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)
    }
}

Keychain Sharing sa pagitan ng mga app

Ang halimbawa ay nagpapakita ng configuration ng Access Group para sa shared access sa Keychain sa pagitan ng mga app ng parehong developer. Nangangailangan ng entitlement keychain-access-groups.

swift
// Capabilities: Keychain Sharing ay naka-enable
// 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)
}

Pinakamahusay na kasanayan sa paggawa gamit ang Keychain

Ang tamang paggamit ng iOS Keychain ay nangangailangan ng pagsunod sa ilang pangunahing panuntunan na pumipigil sa karaniwang mga kahinaan at pagkawala ng data.

Gamitin ang ThisDeviceOnly para sa lahat ng authentication secret: ginagarantiyahan ng kSecAttrAccessibleWhenUnlockedThisDeviceOnly na ang mga token ay hindi mapupunta sa iCloud Backup. Kung ang isang attacker ay makakuha ng access sa backup, ang Keychain data na may ganitong flag ay hindi magiging available. Ang exception ay data na dapat ay available sa lahat ng device ng user (halimbawa, encryption key para sa sariling serbisyo), kung saan gamitin ang kSecAttrAccessibleWhenUnlocked na may kSecAttrSynchronizable.

Huwag mag-imbak ng raw password — mag-imbak ng hash o session token. Apple Security Guide (2025) ay nagrerekomenda na huwag kailanman i-save ang password ng user sa Keychain sa plain text. Sa halip, i-save ang refresh token na nakuha mula sa server pagkatapos ng matagumpay na authentication sa pamamagitan ng OAuth 2.0. Ang password ay ginagamit lamang para makuha ang token at agad na tinatanggal mula sa memorya.

Pangasiwaan nang tama ang mga error sa Keychain: bawat operasyon sa Keychain ay nagbabalik ng OSStatus na dapat suriin. Espesyal na atensyon — errSecItemNotFound (token ay nag-expire o natanggal) at errSecAuthFailed (biometry ay nabigo). Sa unang kaso, ang app ay dapat humiling ng bagong authentication, sa pangalawa — magpakita sa user ng alternatibong paraan (passcode). Huwag kailanman balewalain ang status na errSecItemNotFound — ito ay magdudulot ng pag-crash ng app kapag sinusubukang magbasa ng nil.

Subukan ang Keychain sa totoong device: ang simulator ay walang Secure Enclave at hindi sumusuporta sa biometric ACL. Laging suriin ang mga scenario: unang paglunsad, pag-restore mula sa backup, pagbabago ng device password, pagtanggal at muling pag-install ng app. Sa totoong device, ang Keychain ay pinapanatili pagkatapos tanggalin ang app, ngunit kung hindi ginamit ang flag na kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly — ang flag na ito ay na-clear kapag inalis ang passcode.

I-minimize ang bilang ng mga operasyon sa Keychain: bawat operasyon ng pagbasa o pagsulat ay isang tawag sa system service na Securityd na maaaring makapag-block ng thread. I-cache ang mga nabasang token sa memorya sa panahon ng session at i-access muli ang Keychain lamang sa pag-restart ng app o authentication error (401 mula sa server). iOS ay awtomatikong nagla-lock ng Keychain kapag naka-lock ang device, kaya planuhin ang pagbasa sa pamamagitan ng LAContext na may kahilingan ng biometry.

Mga Madalas Itanong

Maaari ba akong mag-imbak ng data sa Keychain at basahin ito pagkatapos ng restart?

Oo, gamitin ang klase ng proteksyon na kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly o kSecAttrAccessibleAfterFirstUnlock. Ang data ay magiging available pagkatapos ng unang pag-unlock ng device pagkatapos ng restart. Para sa awtomatikong pag-access sa pagsisimula ng app (nang hindi naghihintay ng pag-unlock), gamitin ang kSecAttrAccessibleAlways, ngunit binabawasan nito ang seguridad.

Paano linisin ang Keychain kapag nag-log out ang user?

Tumawag ng SecItemDelete na may query na naglalaman ng kSecClass para sa bawat uri ng data. Para sa kumpletong paglilinis ng lahat ng elemento ng app: SecItemDelete([kSecClass as String: kSecClassGenericPassword] as CFDictionary). Ulitin para sa kSecClassKey, kSecClassCertificate at kSecClassInternetPassword.

Ano ang pagkakaiba sa pagitan ng kSecAttrAccessible at kSecAttrAccessControl?

kSecAttrAccessible ay tumutukoy kung kailan available ang data (sa pag-unlock, pagkatapos ng unang pag-unlock, atbp.). kSecAttrAccessControl ay tumutukoy kung sino ang maaaring mag-access (biometry, passcode, anumang authentication). Sila ay pinagsama: una Protection Class, pagkatapos ACL. Halimbawa, ang data ay available lamang sa pag-unlock AT pagkatapos lamang ng Face ID.

Bakit ang SecItemCopyMatching ay nagbabalik ng errSecItemNotFound?

Mga dahilan: ang elemento ay hindi kailanman na-save, ang elemento ay tinanggal kapag inalis ang passcode (kung ginamit ang kSecAttrAccessibleWhenPasscodeSet), ang app ay muling na-install (ang Keychain ay pinapanatili ngunit hindi nire-restore mula sa backup sa bagong device), ang Access Group o identifier ng developer team ay nagbago. Suriin ang kSecAttrService at kSecAttrAccount.

Paano suriin kung sinusuportahan ng device ang biometry sa Keychain?

Gamitin ang LAContext mula sa LocalAuthentication: tawagan ang context.canEvaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, error: nil). Kung nagbalik ng true — sinusuportahan ng device ang Touch ID o Face ID. Para sa Keychain ACL, gamitin ang flag na biometryCurrentSet (kasalukuyang biometric data lamang) o biometryAny (anumang naunang rehistradong data).

Buod

  • iOS Keychain — imbakan ng mga lihim na protektado ng hardware na may encryption sa pamamagitan ng Secure Enclave at kontrol sa pag-access sa pamamagitan ng ACL.
  • Security framework ay nagbibigay ng mga function na SecItemAdd, SecItemCopyMatching, SecItemUpdate at SecItemDelete para sa paggawa gamit ang mga elemento.
  • Protection Class (kSecAttrAccessible) ay pinili batay sa scenario: WhenUnlockedThisDeviceOnly — standard para sa mga token.
  • ACL na may biometry (kSecAttrAccessControl) ay nagdaragdag ng kinakailangan ng Face ID o Touch ID para sa bawat operasyon ng pagbasa.
  • kSecClassGenericPassword ay sumasakop sa 95% ng mga kaso — pag-iimbak ng mga token, API key, PIN code at mga tala.
  • ThisDeviceOnly ay pumipigil sa pagkopya ng mga lihim sa iCloud Backup — sapilitan para sa mga authentication token.
  • Tamang paghawak ng OSStatus at pagsubok sa totoong device — sapilitang kasanayan para sa maaasahang paggawa gamit ang Keychain.

Gagawa kami ng mobile application na turnkey

Gumagawa ang IT Sectr ng mga iOS at Android application para sa mga startup at negosyo mula noong 2017. Magpapayo kami sa iyo at magmumungkahi ng pinakamahusay na solusyon.

Pag-usapan ang proyekto

Basahin din