Keychain — 핵심 개념, 아키텍처 및 작동 방식

저자: IT Sectr 게시일: 2026-03-14 읽는 시간: 10 분

Keychain은 iOS, watchOS, macOS 및 tvOS에서 비밀번호, 키, 인증서를 하드웨어 수준에서 관리하는 보안 자격 증명 저장소입니다. UserDefaults와 달리 Keychain의 데이터는 암호화되며 애플리케이션 샌드박스별로 격리됩니다. Apple Developer Documentation에 따르면 Keychain은 Secure Enclave 메커니즘과 AES-256 하드웨어 암호화를 사용하여 기밀 정보를 보호합니다.

핵심 포인트

  • Keychain — 하드웨어 암호화를 사용하는 비밀번호, 키, 인증서를 위한 iOS 시스템 저장소
  • Security framework는 Keychain 작업을 위한 C 함수 SecItemAdd, SecItemCopyMatching, SecItemDelete를 제공
  • Keychain 액세스는 앱 샌드박스에 의해 제한되지만 keychain access groups를 통한 공유 액세스 가능
  • kSecAttrAccessible 속성이 보호 수준을 정의: Always부터 WhenUnlockedThisDeviceOnly까지
  • Keychain은 비밀번호, 대칭 및 비대칭 키, X.509 인증서 저장 지원

Keychain이란?

Keychain은 비밀번호, 암호화 키, 인증서 및 기타 민감한 데이터를 안전하게 저장하기 위해 설계된 Apple 운영 체제의 보안 데이터베이스입니다. Keychain은 1999년 Mac OS 8.6에서 처음 등장했으며 iOS에서는 첫 SDK 버전부터 사용 가능합니다.

정의 및 목적

Keychain은 모바일 개발의 근본적인 문제를 해결합니다: 안전하지 않은 파일 시스템에서 비밀(토큰, 비밀번호, 암호화 키)을 저장하는 것입니다. UserDefaults나 SQLite와 달리 Keychain의 데이터는 암호화된 형태로 저장되며 디스크에 쓸 때 자동으로 암호화됩니다.

각 iOS 애플리케이션은 격리된 샌드박스에서 실행되며 자신의 keychain에만 액세스할 수 있습니다. 그러나 개발자는 keychain access groups를 통해 동일한 개발자의 애플리케이션 간에 공유 Keychain 액세스를 구성할 수 있습니다. 사용자의 iCloud Keychain은 종단간 암호화를 통해 기기 간 데이터를 동기화합니다.

Apple Security White Paper(2025)에 따르면 Keychain은 고유 기기 식별자(UID)에 바인딩된 키로 AES-256 하드웨어 암호화를 사용하여 기기에서 추출해도 데이터에 접근할 수 없도록 합니다.

iOS에서 Keychain 작동 방식

Keychain은 계층형 서비스로 작동합니다: 애플리케이션이 Security framework에 액세스하고, Security framework는 암호화된 SQLite Keychain 데이터베이스를 관리하는 securityd 데몬과 통신합니다. 각 레코드는 별도의 키로 암호화되며, 키 자체는 A7 칩 이상 기기에서 Secure Enclave 하드웨어 모듈에 의해 보호됩니다.

Security framework 아키텍처

Security framework는 Keychain Services 작업을 위한 C 인터페이스를 제공합니다. 주요 함수: SecItemAdd(추가), SecItemCopyMatching(검색), SecItemUpdate(업데이트), SecItemDelete(삭제). 각 작업은 요청 유형을 설명하는 CFDictionaryRef 속성 사전을 받습니다.

데이터는 클래스별로 분류됩니다: kSecClassGenericPassword(임의 비밀번호), kSecClassInternetPassword(인터넷 서비스 비밀번호), kSecClassCertificate(인증서), kSecClassKey(암호화 키), kSecClassIdentity(키와 인증서 쌍).

데이터 저장 프로세스

비밀번호를 저장할 때 애플리케이션은 속성을 포함한 사전을 생성합니다: 서비스, 계정, 액세스 수준, 레이블. Security framework는 데이터를 securityd 데몬에 전달하고, 데몬은 기기에 바인딩된 키로 레코드를 암호화하여 Keychain SQLite에 저장합니다. 검색도 유사하게 작동합니다: 속성별 쿼리, 검색, 복호화, 데이터 반환.

중요한 특징: 애플리케이션이 삭제되면 iOS는 자동으로 해당 애플리케이션이 생성한 Keychain 레코드를 지웁니다(iOS 10.3+부터). 애플리케이션을 재설치할 때 iCloud Keychain을 사용하지 않은 경우 이전 설치의 Keychain 데이터를 사용할 수 없습니다.

swift
import Security

func savePassword(service: String, account: String, password: Data) {
    let query: [String: Any] = [
        kSecClass as String: kSecClassGenericPassword,
        kSecAttrService as String: service,
        kSecAttrAccount as String: account,
        kSecValueData as String: password,
        kSecAttrAccessible as String: kSecAttrAccessibleWhenUnlocked
    ]
    SecItemAdd(query as CFDictionary, nil)
}

Keychain 데이터 유형

Keychain은 5가지 주요 데이터 클래스를 지원하며, 각각 고유한 속성 세트와 적용 범위가 있습니다. 클래스 선택에 따라 사용 가능한 검색 키와 데이터 암호화 방식이 결정됩니다.

비밀번호 및 계정

kSecClassGenericPasswordkSecClassInternetPassword 클래스는 문자열 비밀번호 저장용으로 설계되었습니다. 인터넷 버전은 추가로 서버 데이터(도메인, 프로토콜, 포트, 인증 경로)를 저장합니다. GenericPassword는 서버 바인딩 없이 모든 비밀번호 저장에 사용됩니다.

인터넷 비밀번호를 저장할 때 kSecAttrServer(도메인), kSecAttrProtocol(HTTPS, FTP 등), kSecAttrPort, kSecAttrPath를 지정할 수 있습니다. 이를 통해 AutoFill을 통한 자동 입력 시 레코드를 정확히 식별할 수 있습니다.

암호화 키 및 인증서

kSecClassKey 클래스는 대칭(AES) 및 비대칭(RSA, EC) 키를 저장합니다. kSecClassCertificate 클래스는 X.509 인증서를 저장합니다. kSecClassIdentity 클래스는 개인 키와 해당 인증서를 하나의 레코드로 결합합니다.

비대칭 키의 경우 Keychain은 속성을 지원합니다: kSecAttrKeyType(RSA, EC), kSecAttrKeySizeInBits(2048, 256), kSecAttrIsPermanent(Keychain에 저장할지 여부). 인증서의 경우: kSecAttrLabel(사람이 읽을 수 있는 이름), kSecAttrSubject(소유자 DN), kSecAttrIssuer(발급자 DN).

Keychain 클래스목적데이터 유형
kSecClassGenericPassword앱 비밀번호Data(NSString)
kSecClassInternetPassword서버 비밀번호Data + 서버 속성
kSecClassCertificateX.509 인증서SecCertificate
kSecClassKey암호화 키SecKey
kSecClassIdentity키 + 인증서SecIdentity

API를 통한 Keychain 작업

네이티브 iOS 코드에서 Keychain과 상호작용하는 주요 인터페이스는 Security framework의 함수입니다. Swift 및 Objective-C의 경우 편리한 함수로 래핑된 단일 C 인터페이스를 사용할 수 있습니다.

기본 작업 SecItemAdd 및 SecItemCopyMatching

SecItemAdd 함수는 새 항목을 Keychain에 추가합니다. 클래스, 데이터, 속성이 포함된 사전을 입력으로 받고 errSecSuccess(0) 상태 또는 오류 코드를 반환합니다. SecItemCopyMatching 함수는 속성별 검색을 수행하고 발견된 데이터를 반환합니다.

검색에는 kSecReturnData 플래그가 사용됩니다 — true인 경우 함수는 레코드 내용을 반환합니다. kSecMatchLimit 플래그는 결과 수를 결정합니다: kSecMatchLimitOne(하나) 또는 kSecMatchLimitAll(모두).

swift
func readPassword(service: String, account: String) -> Data? {
    let query: [String: Any] = [
        kSecClass as String: kSecClassGenericPassword,
        kSecAttrService as String: service,
        kSecAttrAccount as String: account,
        kSecReturnData as String: true,
        kSecMatchLimit as String: kSecMatchLimitOne
    ]
    var item: CFTypeRef?
    let status = SecItemCopyMatching(query as CFDictionary, &item)
    guard status == errSecSuccess else { return nil }
    return item as? Data
}

레코드 삭제 및 업데이트

SecItemUpdate는 기존 레코드의 속성이나 데이터를 변경할 수 있습니다. SecItemDelete는 전달된 사전과 일치하는 모든 레코드를 삭제합니다. 삭제 시 공유 keychain에서 다른 레코드를 실수로 삭제하지 않도록 충분한 속성을 지정하는 것이 중요합니다.

swift
func deletePassword(service: String, account: String) {
    let query: [String: Any] = [
        kSecClass as String: kSecClassGenericPassword,
        kSecAttrService as String: service,
        kSecAttrAccount as String: account
    ]
    SecItemDelete(query as CFDictionary)
}

액세스 수준 및 데이터 보호

각 Keychain 레코드에는 kSecAttrAccessible 속성이 있으며, 이는 데이터를 읽을 수 있는 시기를 결정합니다. 이는 보안에 매우 중요합니다: 잘못된 액세스 수준은 데이터를 취약하게 만들거나 반대로 필요할 때 사용할 수 없게 만들 수 있습니다.

가용성 상수

kSecAttrAccessibleWhenUnlocked — 기기가 잠금 해제된 경우에만 데이터 사용 가능. kSecAttrAccessibleAfterFirstUnlock — 재부팅 후 첫 잠금 해제 이후 사용 가능. kSecAttrAccessibleAlways — 항상 사용 가능(권장하지 않음). ThisDeviceOnly 접미사는 백업을 통한 데이터 전송을 방지합니다.

Secure Enclave가 있는 기기에서는 Keychain 암호화 키를 생체 인증으로 추가 보호할 수 있습니다: kSecAccessControlBiometryCurrentSet 또는 kSecAccessControlUserPresence. 이렇게 하면 각 읽기 작업에 Face ID 또는 Touch ID가 필요합니다.

iCloud Keychain 및 동기화

iCloud Keychain은 종단간 암호화를 통해 Apple 기기 간에 레코드를 동기화합니다. Apple은 복호화된 데이터에 액세스할 수 없습니다. 동기화를 활성화하려면 kSecAttrSynchronizable 속성을 kCFBooleanTrue 값으로 추가하세요.

중요: 동기화된 레코드에는 ThisDeviceOnly 속성이 포함될 수 없습니다. 다른 기기에서 사용할 수 있어야 하기 때문입니다. 모든 기기를 분실한 경우 iCloud Keychain은 복구 코드 또는 iCloud 복구 키를 통해 복원할 수 있습니다.

액세스 수준 선택 모범 사례

인증 토큰에는 kSecAttrAccessibleWhenUnlockedThisDeviceOnly를 사용하세요 — 데이터는 기기가 잠금 해제된 경우에만 사용 가능하며 백업에 복사되지 않습니다. 백그라운드 작업에 사용 가능해야 하는 인증서에는 kSecAttrAccessibleAfterFirstUnlock을 사용하세요. 민감한 데이터에는 kSecAttrAccessibleAlways를 절대 사용하지 마세요.

동기화가 필요하지 않은 데이터에는 항상 ThisDeviceOnly 접미사를 추가하는 것이 좋습니다. 이렇게 하면 iCloud 또는 iTunes 백업에 비밀이 실수로 복사되는 것을 방지하여 분석 도구로 추출될 수 있는 위험을 막을 수 있습니다. 중요한 데이터의 경우 kSecAccessControlUserPresence와 가용성을 결합하세요 — 레코드 복호화에 생체 인증 또는 암호가 필요합니다.

iCloud Keychain 사용 시 동기화된 레코드는 모든 사용자 기기에서 사용 가능하다는 점에 유의하세요: 공격자가 하나의 기기에 액세스하면 모든 기기의 데이터가 손상될 수 있습니다. 격리된 비밀에는 ThisDeviceOnly를 사용하세요.

자주 묻는 질문

Keychain은 UserDefaults와 어떻게 다른가요?

UserDefaults는 데이터를 .plist 파일에 일반 텍스트로 저장하며 IPA 분석 중에 액세스할 수 있습니다. Keychain은 각 레코드를 개별적으로 암호화하고 하드웨어 암호화를 사용하며 액세스 수준, 생체 인증 및 iCloud를 통한 동기화를 지원합니다.

테스트 중 Keychain을 지우려면 어떻게 하나요?

iOS 시뮬레이터를 시작할 때마다 Keychain이 지워집니다. 실제 기기에서는 앱을 삭제하면 iOS가 해당 개발자의 모든 Keychain 레코드를 제거합니다. 선택적으로 지우려면 적절한 속성과 함께 SecItemDelete를 호출하세요.

두 애플리케이션이 Keychain을 공유할 수 있나요?

네, keychain access groups를 통해 가능합니다. 애플리케이션은 프로비저닝 프로필에 동일한 team ID를 가지고 동일한 keychain-access-groups가 있는 entitlements가 있어야 합니다. 개발자는 Xcode Capabilities에서 공유 액세스를 구성합니다.

Keychain의 최대 데이터 크기는 얼마인가요?

Apple은 엄격한 제한을 문서화하지 않지만 실제로는 레코드당 1~4KB를 초과하지 않는 것이 좋습니다. 더 큰 볼륨의 경우 파일 암호화를 사용하고 키는 Keychain에 저장하며 데이터 자체는 Documents에 저장하세요.

탈옥된 기기에서 Keychain은 안전한가요?

탈옥된 기기에서는 공격자가 루트 액세스 권한을 얻고 Keychain SQLite를 직접 읽을 수 있으므로 Keychain 보호가 낮아집니다. 중요한 데이터의 경우 서버에서 얻은 키로 추가 암호화를 사용하세요.

요약

  • Keychain — AES-256 하드웨어 암호화를 사용하는 비밀번호, 키, 인증서를 위한 iOS 보안 저장소
  • Security framework는 C-API 제공: 쓰기용 SecItemAdd, 읽기용 SecItemCopyMatching, 삭제용 SecItemDelete
  • Keychain 데이터 클래스: GenericPassword, InternetPassword, Certificate, Key, Identity — 각각 고유한 속성 세트
  • kSecAttrAccessible이 액세스 수준 제어: WhenUnlocked, AfterFirstUnlock, Always, ThisDeviceOnly 옵션
  • iCloud Keychain은 kSecAttrSynchronizable 속성으로 종단간 암호화를 통해 기기 간 레코드 동기화
  • 생체 인증(Face ID / Touch ID)이 kSecAccessControlBiometryCurrentSet을 통해 Keychain 액세스 보호
  • OAuth 토큰, 비밀번호, 암호화 키 저장에는 Keychain 사용 — UserDefaults에 비밀을 저장하지 마세요

턴키 방식의 모바일 애플리케이션을 개발해 드립니다

IT Sectr는 2017년부터 스타트업과 기업을 위한 iOS 및 Android 애플리케이션을 만듭니다. 저희가 상담해 드리고 최적의 솔루션을 제안하겠습니다.

프로젝트 논의

더 읽어보기