Table of Contents
iOS에서 Secure Data Storage에 대한 소개
이 문서는 귀하가 웹 사이트를 탐색하는 데 필요한 모든 정보를 저장하는 데 필요한 모든 정보를 저장하는 데 필요한 모든 정보를 저장하는 데 필요한 정보를 제공합니다. 이 문서는 귀하가 웹 사이트를 탐색하는 데 필요한 정보를 저장하는 데 필요한 정보를 제공합니다. 이 문서는 귀하가 웹 사이트를 탐색하는 데 필요한 정보를 제공합니다. 이 문서는 귀하가 웹 사이트를 탐색하는 데 필요한 정보를 저장하는 데 필요한 정보를 제공합니다. 이 문서는 귀하가 웹 사이트를 탐색하는 데 필요한 정보를 저장하는 데 필요한 정보를 제공합니다. 이 문서는 귀하가 웹 사이트를 탐색하는 데 필요한 정보를 수집하는 데 필요한 정보를 제공합니다.
iOS 키 체인에 대한 이해
키 체인은 운영 체제에서 관리 된 안전한 저장 용기입니다. 그것은 암호, 암호화 키 또는 암호화 된 데이터베이스에서 같은 작고 민감한 항목을 저장합니다. 키 체인에 기록 된 데이터는 장치가 잠겨있을 때도 보호됩니다. 키 기능은 다음과 같습니다.
- 휴게용] 하드웨어 백업 AES-256을 사용하여 암호화.
- Access control 장치 패스코드, Touch ID 또는 Face ID를 통해 액세스 제어.
- ]앱 재설치에 따른 지속] (구성되는 경우) 및 옵션 iCloud 동기화.
- Isolation 앱간: 기본적으로, 하나의 앱은 키 체인 액세스 그룹을 공유하지 않는 한 다른 앱의 키 체인 아이템을 읽을 수 없습니다.
키 체인은 큰 블로bs를 위해 설계되지 않습니다; 몇 킬로바이트의 각 항목을 유지. 더 큰 데이터를 위해, API 또는 파일 기반 암호화와 함께 프레임 워크를 사용 고려.
키 체인 서비스 API vs. 제 3 부 Libraries
Apple은 기본 Keychain Services API (C 기반, )를 제공하여 강력하지만 동등합니다. Swift-friendly wrapper를 직접 사용할 수 있습니다. ]KeychainAccess] 또는 ]SwiftKeychainWrapper])에 대한 기본 정보를 읽을 때 API를 기본으로 관리할 수 있습니다. 그러나 API는 API에 대한 기본 정보를 읽을 때 API를 읽을 수 있습니다.
키체인 저장 설정
아무것도 저장하기 전에, 당신은 Keychain 항목 클래스]을 결정해야합니다. 일반적인 암호에 가장 일반적인 ]]입니다. 인터넷 암호 또는 인증서의 경우, 다른 클래스가 있습니다. 각 항목은 항목 설명하는 속성의 세트에 의해 참조됩니다 (CFDictionary).
기본적인 교류는 항상 이 본을 따릅니다:
- 아이템 클래스와 속성을 가진 쿼리 사전을 구축하십시오.
- ] 함수를 호출합니다.], , , ).
- 반환된 (] 또는 오류 코드)를 확인합니다.
코드를 작성하기 전에 보안 모듈을 가져 오기 :
import Security
import Foundation // for Data and String utilities
키 체인에 데이터 저장
일반 비밀번호
현재 사용자의 경우 토큰 (예, JWT)을 저장하려면:
func saveToken(_ token: String, forAccount account: String) -> Bool {
guard let tokenData = token.data(using: .utf8) else { return false }
let query: [String: Any] = [
kSecClass as String: kSecClassGenericPassword,
kSecAttrAccount as String: account,
kSecValueData as String: tokenData,
// Optional: restrict access to when device is unlocked
kSecAttrAccessible as String: kSecAttrAccessibleWhenUnlockedThisDeviceOnly
]
// Delete any existing item first to avoid duplicates
SecItemDelete(query as CFDictionary)
let status = SecItemAdd(query as CFDictionary, nil)
return status == errSecSuccess
}
키 포인트:
- ]는 1차 키로 작용합니다. (예:, user ID 또는 와 같은 상수도 선택).
- 항목이 읽을 수 있을 때 제어합니다. 사용 최고의 보안; 그것은 iCloud 백업을 방지하고 현재 장치에 대한 액세스를 제한합니다.
- 우리는 ]를 호출하여 중복 품목을 축적하는 것을 방지하기 전에. 또는, 당신은 를 사용할 수 있습니다.
액세스 제어 추가 (Biometry 또는 Passcode)
매우 민감한 데이터를 위해서는 Touch ID 또는 Face ID가 필요합니다.
let accessControl = SecAccessControlCreateWithFlags(
nil,
kSecAttrAccessibleWhenUnlockedThisDeviceOnly,
.userPresence, // requires passcode, Face ID, or Touch ID
nil
)
let query: [String: Any] = [
kSecClass as String: kSecClassGenericPassword,
kSecAttrAccount as String: account,
kSecValueData as String: tokenData,
kSecAttrAccessControl as String: accessControl as Any
]
SecItemAdd(query as CFDictionary, nil)
이제 ] 이 항목에 대한 호출은 생체 인식 또는 암호 프롬프트를 유발합니다. ]를 사용하여 LocalAuthentication에서 사용자 상호 작용을 완전히 처리합니다.
Keychain에서 데이터를 검색
저장 된 토큰을 읽기 위해:
func retrieveToken(forAccount account: String) -> String? {
let query: [String: Any] = [
kSecClass as String: kSecClassGenericPassword,
kSecAttrAccount as String: account,
kSecReturnData as String: true,
kSecMatchLimit as String: kSecMatchLimitOne
]
var item: CFTypeRef?
let status = SecItemCopyMatching(query as CFDictionary, &item)
guard status == errSecSuccess,
let data = item as? Data,
let token = String(data: data, encoding: .utf8) else {
return nil
}
return token
}
] ] 를 설정하여 데이터를 다시 얻을 수 있습니다. ] 를 사용하여 단일 결과를 검색합니다. 한계를 오면 API는 배열을 반환 할 수 있습니다.
Important: 접근 제한(biometry)을 사용할 때, ] 호출은 ]를 반환할 수 있습니다. 이 경우를 별도로 처리하고 일반 텍스트 저장으로 다시 떨어뜨리지 않습니다.
업데이트 및 삭제 키 체인 항목
기존 아이템을 업데이트
삭제 및 재 추가의 대신, 사용 :
func updateToken(_ newToken: String, forAccount account: String) -> Bool {
guard let newData = newToken.data(using: .utf8) else { return false }
let query: [String: Any] = [
kSecClass as String: kSecClassGenericPassword,
kSecAttrAccount as String: account
]
let attributesToUpdate: [String: Any] = [
kSecValueData as String: newData
]
let status = SecItemUpdate(query as CFDictionary, attributesToUpdate as CFDictionary)
return status == errSecSuccess
}
이것은 delete+add 보다는 더 능률적, 그리고 잠재적인 인종 상태를 피합니다.
상품 삭제
func deleteItem(forAccount account: String) -> Bool {
let query: [String: Any] = [
kSecClass as String: kSecClassGenericPassword,
kSecAttrAccount as String: account
]
let status = SecItemDelete(query as CFDictionary)
return status == errSecSuccess
}
다른 앱에 속한 항목을 삭제하지 않도록 주의하십시오. 동일한 액세스 그룹을 공유하는 경우 ]]로 쿼리를 할당하십시오.
액세스 제어 및 접근성 특성
]는 when 키 체인 아이템을 읽을 수 있습니다. 앱의 요구를 충족하는 가장 제한적인 옵션을 선택하십시오.
| Attribute | Meaning |
|---|---|
kSecAttrAccessibleWhenUnlocked | Available only while device is unlocked (default). |
kSecAttrAccessibleAfterFirstUnlock | Available after device boots and is unlocked once. Allows background access. |
kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly | Requires a passcode to be set. Strictest option—prevents access even after unlock if passcode is removed. |
kSecAttrAccessibleWhenUnlockedThisDeviceOnly | Same as WhenUnlocked but does not back up to iCloud, and cannot be restored to another device. |
대부분의 앱에서는 ]는 보안과 유용성 사이의 올바른 균형을 잡습니다. 배경에 항목을 읽을 필요가 있다면 (예를 들어, 배경은 토큰을 새로 고침), ]를 사용해야합니다 (그리고 데이터가 약간 덜 보호된다는 것을 받아들입니다).
오류 처리 및 일반적인 Pitfalls
함수는 를 반환합니다. 항상 그것을 확인하고 적절한 실패를 처리하십시오. 일반적인 오류 :
- (–25300) - 아이템은 쿼리에 일치하지 않습니다.
- (–25299) – 이미 같은 주요 키와 항목이 존재합니다 (첫 번째 삭제하지 않은 경우).
- (–128) – 사용자가 생체 인식을 취소했습니다.
- (–25293) – 인증은 유효하지 않은 생체 인식을 실패했습니다.
비강력 상태를 무시하지 마십시오. 은혜로 정렬 : 오류 메시지 또는 재발을 표시하지만, 충돌로 키 체인 외부의 민감한 데이터를 저장하지 마십시오. 액세스 시도하기 전에 생체 이용 가능성을 확인하기 위해 ]을 사용할 수 있습니다.
모범 사례 및 생산 고려 사항
- ]사용자당, 상품 유형당, 원고를 방지하기 위해, 원고의 계정 이름]을 사용합니다.
- Always는 accessibility 속성을 지정합니다. 그렇지 않으면 시스템 기본(])은 적용되며, 이는 이상일 수 없습니다.
- 사용자가 를 로그 아웃 할 때의 클럭 데이터가 모든 알려진 계정과 삭제 항목에 적용됩니다.
- Klock Access Groups를 사용하여 자신의 앱과 공유할 때만 사용할 수 있습니다. 넓은 그룹을 피하십시오.
- Never store 비 민감하는 data (사용자 선호도와 같은) 키체인 사용 ] 또는 데이터베이스 대신.
- ]] ] ] 고급 시나리오에 대한 ].
- ]실제 기기에서 테스트; 시뮬레이터는 하드웨어 백업 스토리지에서 다르게 행동하는 소프트웨어 키체인을 사용합니다.
SwiftUI 및 Async/Await를 가진 Keychain 사용하기
현대 앱의 경우, 배우 또는 동기화 안전 클래스에서 키 체인 작업을 감싸는 주요 스레드를 차단하는. 를 사용하여 예 :
actor KeychainManager {
func saveToken(_ token: String, for account: String) async -> Bool {
// same implementation as above, but now it's safe to call from any context
return saveToken(token, forAccount: account)
}
}
생체 인식을 사용한다면 ] 호출은 나사를 차단하고 사용자 상호 작용을 기다리는 동안 차단할 수 있습니다. 배경 큐에 그것을 감싸거나 더 나은 사용 의 ] 키체인 호출 전에 메서드.
관련 기사
The iOS Keychain is the correct place to store small, sensitive pieces of data. By using the native Keychain Services API, you gain direct control over encryption, accessibility, and authentication policies. Always pair your Keychain usage with solid error handling and remember to clear data when appropriate. For further reading, refer to the Apple Keychain Service Documentation and the Keychain Concepts overview. Adopting these practices will help you ship iOS apps that respect user privacy and withstand security scrutiny.