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


104

제 질문은 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무엇입니까?

1
이에 대한 블로그 항목 이 있습니다.
bobobobo

답변:


179

기본 키는 다음과 같습니다 (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)이 이러한 모든 기본 키에 추가 된 필드 인 것처럼 느껴집니다 .


정말 좋은 대답 같네요! 감사합니다! 확인해 보겠습니다. 다른 사용자의 추가 댓글을 하루나 이틀 정도 기다리고 싶지만, 당신은 현상금에서 +50 점을받을 수있는 뜨거운 후보입니다.
휴 버트 Schölnast

3
좋은 대답입니다! 인증서 및 개인 키에 대한 일반 키 체인 래퍼를 구현하기 위해 며칠 동안 노력하고 있습니다. 이는 문자열 자격 증명 (사용자 이름 / 암호) 만 저장하는 Apple의 샘플 코드와는 많이 다릅니다. 그러나, 나는 당신이 설정할 때 것을 발견 kSecClasskSecClassCertificatekSecClassKey또한 키 체인 검사 항목이합니다 (있는 경우 value)가 이미 저장됩니다. 이렇게하면 동일한 인증서 또는 키를 두 번 추가 할 수 없습니다. 또한 kSecAttrApplicationTag키에 대해 다른 값 을 지정하면 (위의 게시물과 관련하여 고유해야 함) 실패합니다.
Chris

1
kSecClass속성을 테이블 이름 으로 생각 하고 위에 지정된 값을 primary key해당 테이블의 값 으로 생각하면 도움이 될 수 있습니다 .
bobobobo

2
kSecAttrAccount및 의 의미는 무엇입니까 kSecAttrService? -아니면 프로그래머가 결정한 의미를 선택할 수 있습니까?
wcochran 2014-06-17

1
kSecAttrService서비스 kSecAttrAccount를 저장하기위한 것이고 계정 이름을 저장하기위한 것입니다. 다른 것을 저장할 수 있지만 혼란 스러울 수 있습니다.
Tammo Freese 2014-06-18

9

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

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

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

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

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


4

@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의 고유성이 결정됩니다.

이 링크가 질문에 답할 수 있지만 여기에 답변의 필수 부분을 포함하고 참조 용 링크를 제공하는 것이 좋습니다. 링크 된 페이지가 변경되면 링크 전용 답변이 무효화 될 수 있습니다. - 리뷰에서
pwc

이 경우 전체 링크를 복사하는 것을 의미했지만 동의했습니다.
Julian Król

0

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

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

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

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

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

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

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.