### KeyChain Data 저장하기 - KeyChain에 Data를 저장하기 위해 필요한 요소에는 무엇이 있는지 확인해봅시다. - Data, Attribute, KeychainItem은 서로 어떤 관계일까요? : `Data`는 저장하고 싶은 정보, `Attribute`는 데이터에 대한 접근성을 제어하고 검색을 위한 공개된 속성, `keychainItem`은 이 두 값을 모두 포함한 아이템 ![](https://hackmd.io/_uploads/S19UW48h2.png) - 우리가 메인 화면에서 비밀번호를 만들어, Data로 저장하고 싶다면, 어떤 과정을 거쳐야 할까요? : `kSecClass`를 정해준 뒤 `kSecValueData`에 저장하고 싶은 데이터를 `Data`타입으로 변환하여 `Item query`를 만듬 - 필요한 KeychainItem의 각 Attribute가 어떤 의미를 가지는지 이해해봅시다. - `kSecClass`는 저장하는 데이터의 종류 - `kSecAttrAccount`는 계정이름 ```swift static func addPassword(password: String) { let password = password.data(using: .utf8) let addquery: [String: Any] = [kSecClass as String: kSecClassGenericPassword, kSecValueData as String: password] let status = SecItemAdd(addquery as CFDictionary, nil) if status == errSecSuccess { print("비밀번호 등록 성공") } else { print("등록 실패") } } ``` ### KeyChain Data 꺼내오기 - SecItemCopyMatching 메서드의 두 매개변수를 확인해봅시다. - query는 무엇에 활용될까요? : 키체인에 저장된 `Data`를 검색하고 접근하는데 사용 - query 를 구성하는 요소들에는 무엇이 있을까요? : 키체인에 `Data`를 저장할때 사용된 `Attribute`를 포함 - result는 무엇에 활용될까요? : 받아온 값을 저장하는 곳 ```swift static func receivePassword() -> String? { let getquery: [String: Any] = [kSecClass as String: kSecClassGenericPassword, kSecReturnData as String: true] var password: AnyObject? let status = SecItemCopyMatching(getquery as CFDictionary, &password) if status == errSecSuccess { guard let password = password as? Data, let password = String(data: password, encoding: .utf8) else { print("가져오기 실패") return nil } print("비밀번호 가져오기 성공") return password } else { print("가져오기 실패") return nil } } ``` ### KeyChain Data 업데이트하기 ``` swift static func updatePassword(_ changePassword: String) -> Bool { let changePassword = changePassword.data(using: .utf8) let changequery: [String: Any] = [kSecValueData as String: changePassword] let genericQuery: [String: Any] = [kSecClass as String: kSecClassGenericPassword] let status = SecItemUpdate(genericQuery as CFDictionary, changequery as CFDictionary) if status == errSecSuccess { print("비밀번호 변경 성공") return true } else { print("비밀번호 변경 실패") return false } } ``` ### 참고 링크 [🍎 Storing Keys in the Keychain](https://developer.apple.com/documentation/security/certificate_key_and_trust_services/keys/storing_keys_in_the_keychain) [🍎 Searching for Keychain Items](https://developer.apple.com/documentation/security/keychain_services/keychain_items/searching_for_keychain_items) [🍎 Updating and Deleting Keychain Items](https://developer.apple.com/documentation/security/keychain_services/keychain_items/updating_and_deleting_keychain_items) [🍎 Keychain Items](https://developer.apple.com/documentation/security/keychain_services/keychain_items) [🍎 Item Attribute Keys and Values](https://developer.apple.com/documentation/security/keychain_services/keychain_items/item_attribute_keys_and_values)