그동안 나는 UserDefault one tool이였다. 그런데 userdefault에는 간단한 설정들만 하지 중요한 자료들을 저장하면 안된다.
apple이 제공하는 보안프레임워크. 디바이스 안에 암호화된 데이터 저장공간.
로그인 및 암호(해시), 결제데이터, 등 비밀 유지하고 싶은것을 저장.
- 사용자가 직접 제거하지 않는 이상, 앱을 제거하고 설치해도 데이터는 남아있어~
- device lock하면 keychain도 잠기고, 디바이스 unlock하면 풀림.
- 잠긴상태에서는 item에 접근, 복호화 할수 없다.
- 풀린상태에서도 해당 아이템을 생성하고 저장한 어플리케이션에서만 접근이 가능.
keychain은 하나의 암호화된 컨테이너
How To Save?
- 저장할 데이터는 암호화여 keychain item으로 패키징. 그런데 이때 Attribute도 함께 저장.
먼저 item조회했을때 암호화된 데이터가 없다면 사용자가 입력된 정보가 유효한지 인증후 키체인 item으로 저장.
일반적으로 앱은 자기자신의 키체인만 접근 가능. 또한 키체인에 저장된 정보는, 앱을 삭제하더라도 사라지지 않는다. How?
이전에 OS를 공부하면서 배웠던 SandBox개념이 나온다.
-> app을 외부로부터 보호하기 위해 SandBox로 감싸잇고 각 SandBox안에 앱의 bundle, data 저장.
그래서 UserDefault를 사용할경우 SandBoX안에 있어 앱이 삭제되면 사라진다.
하지만 이 KeyChain은 sandbox 밖에 있어서 앱을 지워도 남아있다.
KeyChain의 구성요소 3가지
1. KeyChain: 키체인에 저장되는 데이터, 여러개의 키체인 item을 가질 수 있다.
2. ItemClass: 키체인 item에 저장되는 데이터 종류를 지정할수 있다.
- kSecClassGenericPassword : 일반 암호를 저장할 때 사용.
- kSecAttrService: 키체인 아이템과 연관되어 있는 서비스의 이름
- kSecAttrAccount: 저장할 아이템의 계정 이름 (아이디)
- kSecAttrGeneric: 저장할 아이템의 데이터 (비밀번호)
- kSecClassInternetPassword : 인터넷에서 불러온 암호를 저장할 때 사용
- kSecAttrAccount: 저장할 아이템의 계정 이름 (아이디)
- kSecClassCertificate: 인증서를 저장할때 사용
- kSecClassKey: 암호화 키항목을 저장할 때 사용
- kSecClassIdentity: 아이디 항목을 저장할 때 사용
3. Attribute: item class에 대한 속성 저장.
what is attribute? 데이터에 접근하거나 검색하는 것을 가능하게 한다. 직접적으로 접근하게 하는 것이 아닌 접근가능성을 보여주는 것,
item Class에 따라 설정할수 있는 attributes가 달라진다.
실습을 해보자!!!~~~~!!!
1. Create
private func create(key: String, token: String) -> Bool{
let query: NSDictionary = [
kSecClass: kSecClassGenericPassword,
kSecAttrAccount: key, //저장할 아이템의 계정이름
kSecValueData: token.data(using: .utf8, allowLossyConversion: false) as Any // 저장할 토큰
]
SecItemDelete(query) // keychain key값이 겹치면 저장할수 없기에 삭제.
return SecItemAdd(query as CFDictionary, nil) == errSecSuccess
}
2. read
private func read(key:String) -> String? {
let query: NSDictionary = [
kSecClass: kSecClassGenericPassword,
kSecAttrAccount: key,
kSecReturnData: kCFBooleanTrue as Any, //CFType으로 불러와라
kSecMatchLimit: kSecMatchLimitOne // 중복되는 경우 하나만 가져온다.
]
var dataTypeRef: AnyObject?
let status = SecItemCopyMatching(query, &dataTypeRef) //키체인 아이템을 검색.
if status == errSecSuccess {
let data = dataTypeRef as! Data
let value = String(data: data, encoding: String.Encoding.utf8)
return value
} else{
return nil
}
}
3. delete
private func delete(key: String) -> Bool{
let query: NSDictionary = [
kSecClass: kSecClassInternetPassword,
kSecAttrAccount: key
]
return SecItemDelete(query) == errSecSuccess
}
4. update
private func update(key: String, data: Any) -> Bool {
let previousQuery: NSDictionary = [
kSecClass: kSecClassInternetPassword,
kSecAttrAccount: key
]
let updateQuery: NSDictionary = [kSecValueData: data]
return SecItemUpdate(previousQuery, updateQuery) == errSecSuccess
}
'iOS' 카테고리의 다른 글
Uniform type Identifiers (1) | 2024.04.18 |
---|---|
Coremotion2편- 걷기데이터 & HealthKit (0) | 2024.04.17 |
Fastlane - CI를 해보자 (0) | 2023.08.09 |
Operation (0) | 2023.07.08 |
Race Condition(경쟁상황) (0) | 2023.07.07 |