작은 용량의 데이터를 시큐어하게 저장할수 있게 해주는 서비스이다.

패스워드 뿐만 아니라 다양한 데이터를 저장할 수 있게 해줌.

데이터가 키체인에 저장될 경우 데이터 + 어트리뷰트를 추가해 저장하게 된다 어트리뷰트는 엑세스컨트롤과 아이템 보안의 도움을 준다.
Using SecItemAdd(_ : , _:)
func SecItemAdd(
_ attributes: CFDictionary,
_ result: UnsafeMutablePointer<CFTypeRef?>?
) -> OSStatus
예제코드)
static func saveWithKey(key: String, value: String){
let pwData = value.data(using: .utf8) ?? Data()
let query : [CFString:Any] = [kSecClass: kSecClassGenericPassword,
kSecAttrAccount: key,
kSecValueData:pwData]
let status = SecItemAdd(query as CFDictionary, nil)
if status == errSecSuccess{
log.debug("saved in keychain!!")
}else if status == errSecDuplicateItem{
return
}else{
log.debug("saved in keychain failed !! \\(status)")
}
}
Using SecItemCopyMatching(_: _:)
func SecItemCopyMatching(
_ query: CFDictionary,
_ result: UnsafeMutablePointer<CFTypeRef?>?
) -> OSStatus
ex)
static func getDataWithKey(key:String) -> String?{
let query : [CFString: Any] = [kSecClass: kSecClassGenericPassword,
kSecAttrAccount: key,
kSecReturnAttributes:true,
kSecReturnData: true]
var item : CFTypeRef?
if SecItemCopyMatching(query as CFDictionary, &item) != errSecSuccess{
log.debug("get data In KeyChain Failed!!")
return nil
}
guard let existingIem = item as? [String:Any],
let data = existingIem[kSecValueData as String] as? Data,
let password = String(data:data, encoding: .utf8)
else {
return nil
}
return password
}
SecItemAdd 메소드로 키체인에 존재하는 아이템과 동일한 아이템을 저장하는 경우 에러가 발생함. 어트리뷰트 아이템을 바꿔서 키체인에 추가하더라도 결국에는 키체인이 이전것들과 섞이게 되면서 혼란스러워 질 것 이다 . → update를 사용해라
SecItemUpdate
func SecItemUpdate(
_ query: CFDictionary,
_ attributesToUpdate: CFDictionary
) -> OSStatus
Sample
let status = SecItemUpdate(query as CFDictionary, attributes as CFDictionary)
guard status != errSecItemNotFound else { throw KeychainError.noPassword }
guard status == errSecSuccess else { throw KeychainError.unhandledError(status: status) }
Deletes items that match a search query.
func SecItemDelete(_ query: CFDictionary) -> OSStatus