프로젝트에서 AppKey를 저장해야 하는데, 어디에 저장을 할지 고민이 됐습니다.
UserDefaults, KeyChain 이 생각이 났고 그 차이점을 알아보았습니다.
- UserDefaults는 App 시작시 사용자의 기본 데이터베이스를 key-value 쌍으로 저장하는 인터페이스입니다.
- 런타임에 App이 사용자의 기본 데이터베이스에서 사용하는 기본값을 읽고, 정보를 캐싱해 필요할 때마다 DB를 열필요가 없습니다.
- UserDefaults는 싱글톤 객체입니다.
float
,double
,integer
,boolean
뿐만 아니라
NSData
,NSString
,NSNumber
,NSDate
,NSArray
,NSDictionary
유형의 객체도 저장할 수 있습니다.
쉽게 말해 Info.plist
와 유사한 형태로 저장되는 데이터 저장 공간으로, App 내부 어디서든 데이터를 읽고 저장할 수 있습니다.
쉽게 읽고 저장할 수 있다는 장점이 있지만, 그때문에 보안에 취약합니다.
디바이스에 엑세스할 수 있는 모든 사용자가 쉽게 읽을 수 있어, 최근 검색 목록 등 보안에 민감하지 않은 정보만 저장하는 것이 좋습니다!
또, App 시작시 UserDefaults.plist 파일이 메모리에 로드됩니다.
== 많은 데이터를 저장하면 앱 성능에 상당한 영향을 미친다는 뜻!
- KeyChain은 비밀번호, 신용카드 정보, 인증서 등과 같이 민감한 데이터를 저장할 수 있는 암호화된 데이터베이스입니다.
KeyChain Services API
는 민감한 데이터를 암호화하고, 복호화하여 재사용을 쉽고 안전하게 도와줍니다.- 디바이스가 잠기면 키체인도 잠기고, 디바이스를 열면 키체인도 열리며 잠긴상태에서는 데이터에 접근할 수 없습니다.
쉽게 말해, UserDefaults보다 어렵게 구현해야하지만 더 안전하고, 민감한 정보를 저장하기에 용이하다는 말!
KeyChain은 아래 이미지와 같이
비밀로 저장해야할 Data 와, 접근하기 위해 공개되는 Attributes를 KeyChain Item 으로 패키징해 저장합니다.
위 이미지를 보면, 보호해야할 데이터는 Encryption(암호화)해 Item으로 패키징해 키체인 저장소에 보관합니다.
복잡한 암호화 과정은 애플의 KeyChain Services API
로 쉽게 구현 가능합니다!
KeyChain 사용시 아래의 이미지와 같은 Flow로 동작합니다.
참고: Documentation Archive
참고: 공식문서
KeyChain에 저장된 정보는 App을 삭제해도 사라지지 않는데, 그 이유는 KeyChain이 Sandbox 밖에 저장되기 때문입니다.
Sandbox...? 전 MCN 회사인줄로만 알았어요..^^
반성하며 알아보았읍니다.
아래 이미지와 같이 Sandbox 없다면, App이 App을 실행하는 사용자에 대한 모든 권한을 갖으며, 사용자가 엑세스할 수 있는 모든 리소스에 접근할 수 있게 됩니다.
만약 App이나 App과 연결된 프레임워크 보안에 허점이 발생한다면, 그 허점을 통해 해커가 데이터를 악용할 수 있습니다.
App이 시스템과 어떤 방법으로 상호작용할건지 설정할 수 있습니다.
- 시스템은 App이 작업을 끝내는데 필요한 접근권한만 부여합니다.
사용자에게 인터렉션을 받아, 투명하게 App에 추가 권한을 부여합니다.
- 사용자는 위와 같은 Alert을 통해 App에 추가 접근 권한을 부여합니다.
iOS는 아래 이미지와 같이 App 설치시 각 앱을 Sandbox 저장합니다.
Sandbox는 파일, 환경설정, 네트워크 리소드 등에 대한 App 접근을 제한하는 세분화된 제어 집합으로, 고립되어 있기때문에 데이터를 보호하고 보안을 유지할 수 있습니다.
App은 App내부 데이터 외에는 접근을 할 수 없고,
만약 Sandbox 외부 데이터에 접근하려면, 위에 명시한 바와 같이 Sandbox 정책에 따라 권한을 부여받아야 합니다.
Sandbox 내부 구조