Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |
Tags
- UIKit
- GOMS
- breakpoint
- ios
- unowned
- 광주소프트웨어마이스터고등학교
- xcode
- Swift
- ReactorKit
- 회고
- regex
- keychain
- 순환참조
- Protocol
- 정규식
- Clean Architecture
- UIImage
- pop
- 회고록
- Sync
- UISheetPresentationController
- MVVM
- DI
- Async
- weak
- RenderingMode
Archives
- Today
- Total
minaje
Keychain? UserDefault 쓰면 안돼? 본문
Keychain?
KeyChain은 Apple에서 적용하는 암호화된 데이터 저장 공간(encrypted database)이다.
KeyChain에는 비밀번호, 토큰 등 암호화 해야하는 데이터가 들어간다.
데이터를 Apple에서 제공하는 KeyChain services API를 통해 암호화하고 KeyChain이라는 곳이 저장한다.
이때, Data는 암호화(encryption)하여 패키징을 하게 되고, 이 암호화된 데이터에 접근하기 위한 Attributes도 함께 패키징 된다.
그럼, 실제 데이터에 접근할 때 Attribites 데이터로 가져올 때는 자연스럽게 암호화된 데이터 해독 방식으로 할 수 있도록
Apple이 기본 제공한다.
Keychain의 장점
Keychain의 특징을 알아보자!
- Keychain은 앱은 삭제되더라도, Data는 삭제되지 않는다.
- Keychain에는 잠금 기능이 있다. 잠금 되어 있으면 데이터에 접근 복호화 등 아무것도 하지 못한다.
- 같은 개발자가 구현한 앱이 여러개라면, 그 앱 사이의 Keychain 정보는 공유가 가능하다.
Keychain
데이터 종류
kSecClassGenericPassword : 일반 암호를 저장할 때 사용
kSecClassInternetPassword : 인터넷에서 불러온 암호를 저장할 때 사용
kSecClassCertificate : 인증서를 저장할 때 사용
kSecClassKey : 암호화 키 항목을 저장할 때 사용
kSecClassIdentity : ID 항목을 저장할 때 사용
Keychain Create, Read, Delete
실제로 진행 중인 프로젝트에 accessToken, refreshToken을 관리하는 코드를 짜 보도록 하자.
import UIKit
import Security
struct Const {
struct KeychainKey {
static let accessToken = "accessToken"
static let refreshToken = "refreshToken"
static let accessTokenExp = "accessTokenExp"
static let refreshTokenExp = "refreshTokenExp"
static let authority = "authority"
}
}
class Keychain {
func create(key: String, token: String) {
let query: NSDictionary = [
kSecClass: kSecClassGenericPassword,
kSecAttrAccount: key,
kSecValueData: token.data(using: .utf8, allowLossyConversion: false) as Any
]
SecItemDelete(query) // MARK: Keychain은 key 중복 값이 생기면 저장이 안되니 먼저 삭제를 해준다.
let status = SecItemAdd(query, nil)
assert(status == noErr, "failed to save Token")
}
func read(key: String) -> String? {
let query: NSDictionary = [
kSecClass: kSecClassGenericPassword,
kSecAttrAccount: key,
kSecReturnData: kCFBooleanTrue as Any, //MARK: CFData 타입으로 불러오라는 의미
kSecMatchLimit: kSecMatchLimitOne //MARK: 중복되는 경우, 하나의 값만 불러오라는 의미
]
var dataTypeRef: AnyObject?
let status = SecItemCopyMatching(query, &dataTypeRef)
if status == errSecSuccess {
if let retrievedData: Data = dataTypeRef as? Data {
let value = String(data: retrievedData, encoding: String.Encoding.utf8)
return value
} else { return nil }
} else {
print("failed to loading, status code = (status)")
return nil
}
}
func delete(key: String) {
let query: NSDictionary = [
kSecClass: kSecClassGenericPassword,
kSecAttrAccount: key
]
let status = SecItemDelete(query)
assert(status == noErr, "failed to delete the value, status code = (status)")
}
}
이렇게 Keychain을 생성, 접근, 삭제할 수 있는 함수를 만들어줄 수 있다.
Keychain에 값 넣기
func addKeychainToken() {
self.keychain.create(
key: Const.KeychainKey.accessToken,
token: self.userData.accessToken
)
self.keychain.create(
key: Const.KeychainKey.accessTokenExp,
token: self.userData.accessTokenExp
)
self.keychain.create(
key: Const.KeychainKey.refreshToken,
token: self.userData.refreshToken
)
self.keychain.create(
key: Const.KeychainKey.refreshTokenExp,
token: self.userData.refreshTokenExp
)
self.keychain.create(
key: Const.KeychainKey.authority,
token: self.userData.authority
)
}
이런 식으로 간단하게 keychain에 값을 넣을 수 있다!
self.keychain.read(key: Const.KeychainKey.authority)
접근도 간편하게 위와 같이 할 수 있다.
참고
'iOS' 카테고리의 다른 글
DI - Dependency Injection (0) | 2023.10.18 |
---|---|
Swift의 정규식 (0) | 2023.10.17 |
Swift Regex (0) | 2023.10.17 |