Keychain

Groot·2022년 8월 24일
1

TIL

목록 보기
46/153
post-thumbnail
post-custom-banner

TIL

🌱 난 오늘 무엇을 공부했을까?

📌 Keychain Services - 공식문서

  • 사용자를 대신하여 작은 데이터 청크를 안전하게 저장합니다.

📍 Overview

  • 컴퓨터 사용자는 종종 안전하게 저장해야 하는 작은 비밀을 가지고 있습니다.
  • 예를 들어, 대부분의 사람들은 수많은 온라인 계정을 관리합니다.
  • 각각에 대해 복잡하고 고유한 비밀번호를 기억하는 것은 불가능하지만 적어 두는 것은 안전하지 않고 지루합니다.
  • 사용자는 일반적으로 많은 계정에서 간단한 암호를 재활용하여 이 상황에 대응합니다. 이는 또한 안전하지 않습니다.
  • 키체인 서비스 API는 앱에 키체인이라는 암호화된 데이터베이스에 사용자 데이터의 작은 비트를 저장하는 메커니즘을 제공하여 이 문제를 해결하는 데 도움이 됩니다.
  • 암호를 안전하게 기억하면 사용자가 복잡한 암호를 선택할 수 있습니다.
  • 키체인은 그림 1과 같이 비밀번호에 국한되지 않습니다.
  • 신용 카드 정보 또는 짧은 메모와 같이 사용자가 명시적으로 관심을 갖는 다른 비밀을 저장할 수 있습니다.
  • 사용자가 필요로 하지만 인식하지 못하는 항목을 저장할 수도 있습니다.
  • 예를 들어 인증서, 키 및 신뢰 서비스로 관리하는 암호화 키 및 인증서를 통해 사용자는 보안 통신에 참여하고 다른 사용자 및 장치와 신뢰를 구축할 수 있습니다.
  • 키체인을 사용하여 이러한 항목도 보관할 수 있습니다.
    • 그림 1 키체인에서 사용자의 비밀 보호

Keychain Services - 공식문서


📌 Storing Keys in the Keychain - 공식문서

  • 키체인에 암호화 키를 저장하고 액세스합니다.

📍 Overview

  • 키체인은 암호 및 암호화 키와 같은 작은 비밀을 저장하기에 가장 좋은 장소입니다.
  • 키체인 서비스 API의 기능을 사용하여 키체인 항목을 추가, 검색, 삭제 또는 수정합니다.
  • Apple CryptoKit 프레임워크로 생성한 암호화 키를 저장하는 방법에 대한 정보는 키체인에 CryptoKit 키 저장을 참조하십시오.

📍 Create a Query Dictionary

  • 새 암호화 키 생성에 설명된 대로 키를 직접 생성하면 해당 프로세스의 암시적 부분으로 키체인에 저장할 수 있습니다.
  • 다른 방법으로 키를 얻은 경우에도 키체인에 저장할 수 있습니다.
  • 이렇게 하려면 항목을 포함하고 설명하는 쿼리 사전을 만드는 것으로 시작합니다.
    let key = <# a key #>
    let tag = "com.example.keys.mykey".data(using: .utf8)!
    let addquery: [String: Any] = [kSecClass as String: kSecClassKey,
                                   kSecAttrApplicationTag as String: tag,
                                   kSecValueRef as String: key]
  • 이 쿼리 사전은 kSecClass 항목에 대한 kSecClassKey 값을 사용하여 키 항목(인증서, ID 또는 암호와 반대)을 나타냅니다.
  • 또한 나중에 검색할 때 키를 다른 키와 구별할 수 있도록 하는 애플리케이션 태그를 적용합니다.

📍 Store the Item

  • SecItemAdd(::) 함수를 사용하여 항목을 실제로 저장합니다.
    let status = SecItemAdd(addquery as CFDictionary, nil)
    guard status == errSecSuccess else { throw <# an error #> }

📍 Retrieve the Item

  • 키를 검색하려면 동일한 애플리케이션 태그를 사용하여 다른 쿼리 사전을 구성합니다.
    let getquery: [String: Any] = [kSecClass as String: kSecClassKey,
                               kSecAttrApplicationTag as String: tag,
                               kSecAttrKeyType as String: kSecAttrKeyTypeRSA,
                               kSecReturnRef as String: true]
  • 위의 사전은 키가 비대칭 키 쌍 생성에서와 같이 kSecAttrKeyTypeRSA 유형이어야 하고 해당 예제 이상에서 사용된 태그가 있어야 함을 나타냅니다.
  • 마지막 줄은 검색이 키 참조(예: 실제 키 데이터와 반대)를 반환해야 한다고 말합니다.

    이것은 필요한 만큼 검색을 구체화하지 않는 간단한 쿼리입니다. 추가 방법은 아래의 검색 구체화를 참조하십시오.

  • 이 쿼리를 SecItemCopyMatching(::) 함수와 함께 사용하여 검색을 실행하고 제공한 빈 참조를 채웁니다.
    var item: CFTypeRef?
    let status = SecItemCopyMatching(query as CFDictionary, &item)
    guard status == errSecSuccess else { throw <# an error #> }
    let key = item as! SecKey
  • 호출이 성공하면 상태 결과에 표시된 대로 반환된 키 참조를 사용하여 암호화 작업을 수행할 수 있습니다.
  • Objective-C에서 이 방법으로 검색한 키를 모두 사용한 후에는 메모리를 해제해야 합니다.
  • Swift에서 시스템은 객체의 메모리를 관리합니다.
  • 위의 예에서 쿼리는 특정 키 클래스(공개, 비공개 또는 대칭) 또는 기타 키 특성으로 검색을 제한하지 않습니다.
  • 태그 및 유형에 대해서만 일치하며 첫 번째 성공적인 일치에 대한 참조를 반환합니다.
  • 지정된 유형의 모든 키에 대해 고유한 태그를 사용하지 않으면 검색을 실행할 때 찾고 있던 키를 얻지 못할 수 있습니다.
  • 일치하는 첫 번째 키만 반환되고 원하는 키일 수도 있고 아닐 수도 있기 때문입니다.
  • 이를 처리하는 몇 가지 방법이 있습니다.
    • 검색을 확장합니다.
      • 단일 키 참조 대신 kSecMatchLimitAll 값을 사용하여 쿼리 사전에 kSecMatchLimit 항목을 추가하면 SecItemCopyMatching(::)은 관심 있는 키를 찾기 위해 검사할 수 있는 키 참조 배열을 생성합니다.
    • 검색 범위를 좁힙니다.
      • 키 크기 또는 키 클래스와 같이 키를 구별하는 다른 속성이 있는 경우 검색을 수행하기 전에 해당 항목을 쿼리 사전에 추가하십시오.
    • 처음부터 태그를 재사용하지 마십시오.
      • 주어진 태그 및 유형(또는 다른 구별되는 특성)이 있는 키를 추가하기 전에 동일한 특성을 가진 키체인에서 기존 키를 읽으십시오.
      • 잠재적인 중복 키를 찾으면 원래 키를 재사용하고 새 키 생성을 건너뛰거나, 다른 태그를 사용하여 새 키를 생성하거나, 새 키를 추가하기 전에 SecItemDelete(_:) 함수를 사용하여 이전 키를 삭제하십시오.

Storing Keys in the Keychain - 공식문서

profile
I Am Groot
post-custom-banner

0개의 댓글