[objective-c] 키 체인 항목을 고유하게 만드는 것은 무엇입니까 (iOS에서)?

제 질문은 iOS (iPhone, iPad 등)의 키 체인에 관한 것입니다. Mac OS X에서 키 체인을 구현하면 같은 대답으로 같은 질문이 제기된다고 생각합니다 (확실하지 않습니다).


iOS는 5 가지 유형 (클래스)의 키 체인 항목을 제공합니다. kSecClass유형을 결정하려면 키 에 대해 다음 5 개 값 중 하나를 선택해야합니다 .

kSecClassGenericPassword  used to store a generic password
kSecClassInternetPassword used to store an internet password
kSecClassCertificate      used to store a certificate
kSecClassKey              used to store a kryptographic key
kSecClassIdentity         used to store an identity (certificate + private key)

오랜 시간 동안 사과 문서, 블로그 및 포럼 항목을 읽은 후 유형의 키 체인 항목이 kSecClassGenericPassword속성 kSecAttrAccessGroup, kSecAttrAccount및 에서 고유성을 얻는다는 것을 알게되었습니다 kSecAttrService.

요청 1의 세 속성이 요청 2와 같으면 다른 속성에 관계없이 동일한 일반 비밀번호 키 체인 항목을받습니다. 이 속성 중 하나 (또는 ​​둘 또는 모두)가 해당 값을 변경하면 다른 항목을 얻게됩니다.

그러나 kSecAttrService유형의 항목에만 사용할 수 kSecClassGenericPassword있으므로 다른 유형의 항목의 “고유 키”의 일부가 될 수 없으며 어떤 속성이 키 체인 항목을 고유하게 결정하는지 명확하게 나타내는 문서가없는 것 같습니다.

“GenericKeychain”의 “KeychainItemWrapper”클래스에있는 샘플 코드는 속성 kSecAttrGeneric을 사용하여 항목을 고유하게 만들지 만 이는 버그입니다. 이 예의 두 항목 kSecAttrAccessGroup은 서로 다르기 때문에 두 개의 개별 항목으로 만 저장됩니다 (하나는 액세스 그룹 세트가 있고 다른 하나는 해제 할 수 있음). 액세스 그룹없이 Apple의을 사용하여 두 번째 비밀번호를 추가하려고 KeychainItemWrapper하면 실패합니다.

제 질문에 답해주세요.

  • 그것은 사실이다의 조합 kSecAttrAccessGroup, kSecAttrAccount그리고 kSecAttrServicekSecClass는 키 체인 항목의 “고유 키가” kSecClassGenericPassword?
  • 키 체인 항목이 고유 kSecClass하지 않은 경우 고유하게 만드는 속성은 kSecClassGenericPassword무엇입니까?


답변

기본 키는 다음과 같습니다 (Apple의 오픈 소스 파일에서 파생 됨, Schema.m4 , KeySchema.m4SecItem.cpp 참조 ).

  • 클래스의 키 체인 항목의 kSecClassGenericPassword경우 기본 키는 kSecAttrAccount및 의 조합입니다
    kSecAttrService.
  • 클래스의 키 체인 항목에 대해 kSecClassInternetPassword, 기본 키의 조합입니다 kSecAttrAccount, kSecAttrSecurityDomain, kSecAttrServer, kSecAttrProtocol, kSecAttrAuthenticationType, kSecAttrPortkSecAttrPath.
  • class의 키 체인 항목의 kSecClassCertificate경우 기본 키는 kSecAttrCertificateType, kSecAttrIssuer및 의 조합입니다 kSecAttrSerialNumber.
  • 클래스의 키 체인 항목에 대해 kSecClassKey, 기본 키의 조합입니다 kSecAttrApplicationLabel, kSecAttrApplicationTag, kSecAttrKeyType,
    kSecAttrKeySizeInBits, kSecAttrEffectiveKeySize,와 창조자, 아직 SecItem에 의해 노출되지 않은 날짜와 종료 날짜를 시작합니다.
  • 클래스의 키 체인 항목의 kSecClassIdentity경우 오픈 소스 파일에서 기본 키 필드에 대한 정보를 찾지 못했지만 ID는 개인 키와 인증서의 조합이므로 기본 키가 기본 키의 조합이라고 가정합니다. kSecClassKey및에 대한 필드 kSecClassCertificate.

각 키 체인 항목은 키 체인 접근 그룹에 속하므로 키 체인 접근 그룹 (필드 kSecAttrAccessGroup)이 이러한 모든 기본 키에 추가 된 필드 인 것처럼 느껴집니다 .


답변

요 전에이 질문과 관련된 버그 (iOS 7.1)에 부딪 혔습니다. 내가 사용하던 SecItemCopyMatching읽기 위해 kSecClassGenericPassword항목을하며 돌아 유지 errSecItemNotFound하더라도 (-25300)를 kSecAttrAccessGroup, kSecAttrAccount그리고 kSecAttrService모든 키 체인 항목을 일치했다.

결국 나는 kSecAttrAccessible그것이 일치하지 않는다는 것을 깨달았 습니다. 키 체인의 값은 pdmn = dk ( kSecAttrAccessibleAlways)를 보유했지만 kSecAttrAccessibleWhenUnlocked.

물론이 값에 대한 첫 번째 장소에 필요하지 않은 SecItemCopyMatching,하지만이 OSStatus아니 었 errSecParamerrSecBadReq하지만 단지 errSecItemNotFound(-25300)가 조금 까다 발견하게한다.

들어 SecItemUpdate저도 같은 문제가 발생하지만,이 방법에서도 동일한 사용했다 kSecAttrAccessible에서 query매개 변수가 작동하지 않았다. 이 속성을 완전히 제거해야만 수정되었습니다.

이 의견이 여러분 중 일부를 위해 소중한 디버깅 순간을 절약 할 수 있기를 바랍니다.


답변

@Tammo Freese가 제공 한 답변이 올바른 것 같습니다 (모든 기본 키를 언급하지는 않음). 문서에서 증거를 찾고있었습니다. 결국 찾았다:

각 비밀 등급에 대한 기본 키를 언급하는 Apple 문서 (아래 인용문) :

시스템은 해당 키 체인에 동일한 복합 기본 키 세트가있는 동일한 클래스의 항목이 이미있는 경우 해당 키 체인에 대한 항목이 중복 된 것으로 간주합니다. 모든 클래스 에서 몇 가지 속성이 공통적으로 사용 되지만 키 체인 항목의 각 클래스에는 다른 기본 키 세트가 있습니다. 특히, 해당되는 경우 kSecAttrSynchronizable 및 kSecAttrAccessGroup은 기본 키 세트의 일부입니다 . 추가 클래스 별 기본 키는 다음과 같습니다.

  • 일반 암호의 경우 기본 키 에는 kSecAttrAccount 및 kSecAttrService가 포함됩니다.
  • 인터넷 암호의 경우 기본 키 에는 kSecAttrAccount, kSecAttrSecurityDomain, kSecAttrServer, kSecAttrProtocol, kSecAttrAuthenticationType, kSecAttrPort 및 kSecAttrPath가 포함됩니다.
  • 인증서의 경우 기본 키 에는 kSecAttrCertificateType, kSecAttrIssuer 및 kSecAttrSerialNumber가 포함됩니다.
  • 키 항목의 경우 기본 키 에는 kSecAttrKeyClass, kSecAttrKeyType, kSecAttrApplicationLabel, kSecAttrApplicationTag, kSecAttrKeySizeInBits 및 kSecAttrEffectiveKeySize가 포함됩니다.
  • 인증서와 개인 키가 함께 번들 된 ID 항목의 경우 기본 키는 인증서와 동일합니다. 개인 키는 두 번 이상 인증 될 수 있으므로 인증서의 고유성에 따라 ID의 고유성이 결정됩니다.

답변

다음은 이 Apple 문서 페이지 의 “검색 가능성 보장”섹션에있는 키 체인 항목의 고유성에 대한 또 다른 유용한 정보 입니다.

나중에 항목을 찾을 수 있도록 속성에 대한 지식을 사용합니다. 이 예에서 서버와 계정은 항목의 구별 특성입니다. 상수 속성 (여기서는 서버)의 경우 조회 중에 동일한 값을 사용하십시오. 반대로 account 속성은 런타임에 사용자가 제공 한 값을 보유하기 때문에 동적입니다. 앱이 다양한 속성 (예 : 동일한 서버의 다른 계정에 대한 비밀번호)을 가진 유사한 항목을 추가하지 않는 한 이러한 동적 속성을 검색 매개 변수로 생략하고 대신 항목과 함께 검색 할 수 있습니다. 결과적으로 암호를 찾을 때 해당 사용자 이름도 얻게됩니다.

앱에서 다양한 동적 속성을 가진 항목을 추가하는 경우 검색 중에 항목을 선택할 수있는 방법이 필요합니다. 한 가지 옵션은 항목에 대한 정보를 다른 방식으로 기록하는 것입니다. 예를 들어 Core Data 모델에 사용자 기록을 보관하는 경우 키 체인 서비스를 사용하여 암호 필드를 저장 한 후 사용자 이름을 저장합니다. 나중에 데이터 모델에서 가져온 사용자 이름을 사용하여 암호 검색 조건을 지정합니다.

다른 경우에는 더 많은 속성을 추가하여 항목을 추가로 특성화하는 것이 합리적 일 수 있습니다. 예를 들어, kSecAttrLabel원래 추가 쿼리에 속성을 포함 하여 특정 용도로 항목을 표시하는 문자열을 제공 할 수 있습니다. 그러면 나중에이 속성을 사용하여 검색 범위를 좁힐 수 있습니다.

kSecClassInternetPassword예제에서는 클래스 항목 이 사용되었지만 다음과 같은 메모가 있습니다.

키 체인 서비스는 관련 kSecClassGenericPassword 항목 클래스도 제공합니다. 일반 암호는 대부분 인터넷 암호와 유사하지만 원격 액세스에 특정한 특정 속성이 없습니다 (예 : kSecAttrServer 속성이 없음). 이러한 추가 속성이 필요하지 않으면 대신 일반 암호를 사용하십시오.


답변