키 및 ID 증명

키 저장소는 제어된 방식으로 암호화 키를 생성, 저장 및 사용하는 데 더 안전한 장소를 제공합니다. 하드웨어 지원 키 저장소를 사용할 수 있고 사용하고 있다면 키 자료는 기기에서 추출하는 것으로부터 더 안전해지고 Keymaster는 풀기 어려운 제한을 시행합니다.

하지만 이는 키 저장소 키가 하드웨어 지원 저장소에 있다고 알려진 경우에만 적용됩니다. Keymaster 1에서는 앱 또는 원격 서버가 이 경우가 맞는 건지 확실하게 확인할 방법이 없었습니다. 키 저장소 데몬은 사용할 수 있는 Keymaster HAL을 로드하고 키의 하드웨어 지원에 관해 HAL이 알려준 대로 신뢰했습니다.

이를 해결하기 위해 Keymaster는 Android 7.0(Keymaster 2)에 키 증명과 Android 8.0(Keymaster 3)에 ID 증명을 도입했습니다.

키 증명은 비대칭 키 쌍의 하드웨어 지원 여부, 키의 속성 및 사용 제약 조건은 무엇인지를 확인하는 강력한 방법을 제공합니다.

ID 증명을 사용하면 기기에서 일련번호 또는 IMEI와 같은 하드웨어 식별자 증명을 제공할 수 있습니다.

키 증명

키 증명을 지원하기 위해 Android 7.1에서는 HAL에 태그, 유형 및 메서드 집합을 도입했습니다.

태그

  • Tag::ATTESTATION_CHALLENGE
  • Tag::INCLUDE_UNIQUE_ID
  • Tag::RESET_SINCE_ID_ROTATION

유형

Keymaster 2 이하

typedef struct {
    keymaster_blob_t* entries;
    size_t entry_count;
} keymaster_cert_chain_t;

AttestKey 메서드

Keymaster 3

    attestKey(vec<uint8_t> keyToAttest, vec<KeyParameter> attestParams)
        generates(ErrorCode error, vec<vec<uint8_t>> certChain);

Keymaster 2 이하

keymaster_error_t (*attest_key)(const struct keymaster2_device* dev,
        const keymaster_key_blob_t* key_to_attest,
        const keymaster_key_param_set_t* attest_params,
        keymaster_cert_chain_t* cert_chain);
  • dev는 Keymaster 기기 구조입니다.
  • keyToAttestgenerateKey에서 반환되는 키 blob이며 증명은 키 blob을 위해 생성됩니다.
  • attestParams는 증명에 필요한 매개변수의 목록입니다. 이 목록에는 Tag::APPLICATION_IDTag::APPLICATION_DATA 외에도 Tag::ATTESTATION_CHALLENGE가 포함되고 Tag::RESET_SINCE_ID_ROTATION도 포함될 수 있습니다. 앞의 두 태그가 키 생성 중에 지정되었다면 키 blob을 복호화하는 데 필요합니다.
  • certChain은 출력 매개변수이며 인증서의 배열을 반환합니다. 항목 0은 증명 인증서이며 keyToAttest에서 키를 인증하고 인증 확장을 포함합니다.

attestKey 메서드는 언제든지 호출될 수 있고 승인 제약 조건을 충족하지 않아도 되므로 증명된 키의 공개 키 연산으로 간주합니다. 예를 들어 사용 시 증명된 키에 사용자 인증이 필요하다면 증명은 사용자 인증 없이 생성될 수 있습니다.

증명 인증서

증명 인증서는 표준 X.509 인증서이며 증명된 키의 설명을 포함하는 선택적 증명 확장을 사용합니다. 인증서는 인증된 증명 키로 서명됩니다. 증명 키는 키 증명과 다른 알고리즘을 사용할 수 있습니다.

증명 인증서에는 아래 표의 필드가 포함되며 추가 필드는 포함될 수 없습니다. 일부 필드는 고정된 필드 값을 지정합니다. CTS 테스트는 인증서 콘텐츠가 정의된 것과 정확히 일치하는지 확인합니다.

Certificate SEQUENCE

필드 이름(RFC 5280 참조)
tbsCertificate TBSCertificate SEQUENCE
signatureAlgorithm 키 서명에 사용하는 알고리즘의 AlgorithmIdentifier:
EC 키의 경우 ECDSA이며 RSA 키의 경우 RSA입니다.
signatureValue BIT STRING이며 ASN.1 DER로 인코딩된 tbsCertificate로 계산된 서명입니다.

TBSCertificate SEQUENCE

필드 이름(RFC 5280 참조)
version INTEGER 2(v3 인증서를 의미함)
serialNumber INTEGER 1(고정 값: 모든 인증서에서 동일함)
signature 키 서명에 사용하는 알고리즘의 AlgorithmIdentifier: EC 키의 경우 ECDSA이며 RSA 키의 경우 RSA입니다.
issuer 배치 증명 키의 subject 필드와 동일합니다.
validity Tag::ACTIVE_DATETIMETag::USAGE_EXPIRE_DATETIME의 값을 포함하는 두 날짜의 SEQUENCE입니다. 이러한 값은 1970년 1월 1일 이후 시간을 밀리초 단위로 나타낸 것입니다. 인증서의 올바른 날짜 표현은 RFC 5280을 참조하세요.
Tag::ACTIVE_DATETIME이 없다면 Tag::CREATION_DATETIME의 값을 사용합니다. Tag::USAGE_EXPIRE_DATETIME이 없다면 배치 증명 키 인증서의 만료일을 사용합니다.
subject CN = 'Android Keystore Key'(고정 값: 모든 인증서에서 동일함)
subjectPublicKeyInfo 증명된 공개 키를 포함하는 SubjectPublicKeyInfo입니다.
extensions/Key Usage digitalSignature: 키에 KeyPurpose::SIGN 또는 KeyPurpose::VERIFY 목적이 있다면 설정합니다. 다른 모든 비트는 설정되지 않습니다.
extensions/CRL Distribution Points 값이 정해지지 않았습니다.
extensions/"attestation" OID는 1.3.6.1.4.1.11129.2.1.17이며 콘텐츠는 아래의 증명 확장 섹션에 정의되어 있습니다. 모든 X.509 인증서 확장과 마찬가지로 콘텐츠는 증명 SEQUENCE의 DER 인코딩을 포함하는 OCTET_STRING으로 표현됩니다.

증명 확장

attestation 확장에는 키와 연결된 Keymaster 승인의 전체 설명이 포함되며 Android와 Keytmaster HAL에서 사용된 것처럼 승인 목록에 직접 대응되는 구조로 되어 있습니다. 승인 목록의 각 태그는 ASN.1 SEQUENCE 항목에 의해 표시되며 마스킹이 해제된 유형 설명어(4개의 상위 비트) 외에 명시적으로 Keymaster 태그 번호로 태그가 지정됩니다.

예를 들어 Keymaster 3에서 Tag::PURPOSE는 types.hal에 ENUM_REP | 1로 정의되어 있습니다. 증명 확장의 경우 ENUM_REP 값이 삭제되며 태그 1을 남겨둡니다. (Keymaster 2 이하의 경우 KM_TAG_PURPOSE는 keymaster_defs.h에 정의되어 있음)

값은 다음 표에 따라 ASN.1 유형으로 간단하게 변환됩니다.

Keymaster 유형 ASN.1 유형
ENUM INTEGER
ENUM_REP INTEGER로 구성된 SET
UINT INTEGER
UINT_REP INTEGER로 구성된 SET
ULONG INTEGER
ULONG_REP INTEGER로 구성된 SET
DATE INTEGER(1970년 1월 1일 00:00:00 GMT 이후의 밀리초)
BOOL NULL(Keymaster에서 태그가 있으면 참, 없으면 거짓을 의미함.
동일한 시맨틱이 ASN.1 인코딩에 적용됨)
BIGNUM 현재 사용되지 않으므로 정의된 매핑이 없음
BYTES OCTET_STRING

스키마

증명 확장 콘텐츠는 다음 ASN.1 스키마로 설명합니다.

KeyDescription ::= SEQUENCE {
  attestationVersion         INTEGER, # KM2 value is 1. KM3 value is 2. KM4 value is 3.
  attestationSecurityLevel   SecurityLevel,
  keymasterVersion           INTEGER,
  keymasterSecurityLevel     SecurityLevel,
  attestationChallenge       OCTET_STRING,
  uniqueId                   OCTET_STRING,
  softwareEnforced           AuthorizationList,
  teeEnforced                AuthorizationList,
}

SecurityLevel ::= ENUMERATED {
  Software                   (0),
  TrustedEnvironment         (1),
  StrongBox                  (2),
}

AuthorizationList ::= SEQUENCE {
  purpose                     [1] EXPLICIT SET OF INTEGER OPTIONAL,
  algorithm                   [2] EXPLICIT INTEGER OPTIONAL,
  keySize                     [3] EXPLICIT INTEGER OPTIONAL.
  digest                      [5] EXPLICIT SET OF INTEGER OPTIONAL,
  padding                     [6] EXPLICIT SET OF INTEGER OPTIONAL,
  ecCurve                     [10] EXPLICIT INTEGER OPTIONAL,
  rsaPublicExponent           [200] EXPLICIT INTEGER OPTIONAL,
  rollbackResistance          [303] EXPLICIT NULL OPTIONAL, # KM4
  activeDateTime              [400] EXPLICIT INTEGER OPTIONAL
  originationExpireDateTime   [401] EXPLICIT INTEGER OPTIONAL
  usageExpireDateTime         [402] EXPLICIT INTEGER OPTIONAL
  noAuthRequired              [503] EXPLICIT NULL OPTIONAL,
  userAuthType                [504] EXPLICIT INTEGER OPTIONAL,
  authTimeout                 [505] EXPLICIT INTEGER OPTIONAL,
  allowWhileOnBody            [506] EXPLICIT NULL OPTIONAL,
  trustedUserPresenceRequired [507] EXPLICIT NULL OPTIONAL, # KM4
  trustedConfirmationRequired [508] EXPLICIT NULL OPTIONAL, # KM4
  unlockedDeviceRequired      [509] EXPLICIT NULL OPTIONAL, # KM4
  allApplications             [600] EXPLICIT NULL OPTIONAL,
  applicationId               [601] EXPLICIT OCTET_STRING OPTIONAL,
  creationDateTime            [701] EXPLICIT INTEGER OPTIONAL,
  origin                      [702] EXPLICIT INTEGER OPTIONAL,
  rollbackResistant           [703] EXPLICIT NULL OPTIONAL, # KM2 and KM3 only.
  rootOfTrust                 [704] EXPLICIT RootOfTrust OPTIONAL,
  osVersion                   [705] EXPLICIT INTEGER OPTIONAL,
  osPatchLevel                [706] EXPLICIT INTEGER OPTIONAL,
  attestationApplicationId    [709] EXPLICIT OCTET_STRING OPTIONAL, # KM3
  attestationIdBrand          [710] EXPLICIT OCTET_STRING OPTIONAL, # KM3
  attestationIdDevice         [711] EXPLICIT OCTET_STRING OPTIONAL, # KM3
  attestationIdProduct        [712] EXPLICIT OCTET_STRING OPTIONAL, # KM3
  attestationIdSerial         [713] EXPLICIT OCTET_STRING OPTIONAL, # KM3
  attestationIdImei           [714] EXPLICIT OCTET_STRING OPTIONAL, # KM3
  attestationIdMeid           [715] EXPLICIT OCTET_STRING OPTIONAL, # KM3
  attestationIdManufacturer   [716] EXPLICIT OCTET_STRING OPTIONAL, # KM3
  attestationIdModel          [717] EXPLICIT OCTET_STRING OPTIONAL, # KM3
  vendorPatchLevel            [718] EXPLICIT INTEGER OPTIONAL, # KM4
  bootPatchLevel              [719] EXPLICIT INTEGER OPTIONAL, # KM4
}

RootOfTrust ::= SEQUENCE {
  verifiedBootKey            OCTET_STRING,
  deviceLocked               BOOLEAN,
  verifiedBootState          VerifiedBootState,
  verifiedBootHash           OCTET_STRING, # KM4
}

VerifiedBootState ::= ENUMERATED {
  Verified                   (0),
  SelfSigned                 (1),
  Unverified                 (2),
  Failed                     (3),
}

KeyDescription 필드

keymasterVersionattestationChallenge 필드는 태그 대신 위치를 기준으로 식별되므로 인코딩된 양식의 태그는 필드 유형만 지정합니다. 나머지 필드는 스키마에 지정된 대로 암시적으로 태그가 지정됩니다.

필드 이름 유형
attestationVersion INTEGER 증명 스키마 버전: 1, 2 또는 3
attestationSecurity SecurityLevel 이 증명의 보안 수준. 하드웨어 지원 키의 소프트웨어 증명을 얻을 수 있습니다. 이러한 증명은 Android 시스템이 도용됐다면 신뢰할 수 없습니다.
keymasterVersion INTEGER Keymaster 기기의 버전: 0, 1, 2, 3 또는 4
keymasterSecurity SecurityLevel Keymaster 구현의 보안 수준.
attestationChallenge OCTET_STRING 증명 요청에 지정된 Tag::ATTESTATION_CHALLENGE
uniqueId OCTET_STRING 키에 Tag::INCLUDE_UNIQUE_ID가 있는 경우에 존재하는 선택적 고유 ID
softwareEnforced AuthorizationList 선택사항, TEE에서 시행하지 않는 Keymaster 승인(있는 경우)
teeEnforced AuthorizationList 선택 사항, TEE에서 시행하는 Keymaster 승인(있는 경우)

AuthorizationList 필드

AuthorizationList 필드는 모두 선택사항이며 마스킹이 해제된 유형 비트를 사용하여 Keymaster 태그 값으로 식별됩니다. 명시적 태그 지정이 사용되므로 더 쉽게 파싱하기 위해 필드에는 ASN.1 유형을 나타내는 태그도 포함됩니다.

각 필드 값에 관한 자세한 내용은 Keymaster 3의 경우 types.hal, Keymaster 2 이하의 경우 keymaster_defs.h를 참조하세요. Keymaster 태그 이름은 KM_TAG 접두사를 생략하고 나머지 부분을 카멜 표기법으로 변경하여 필드 이름으로 변환하였으므로 Tag::KEY_SIZEkeySize가 되었습니다.

RootOfTrust 필드

RootOfTrust 필드는 위치를 기준으로 식별됩니다.

필드 이름 유형
verifiedBootKey OCTET_STRING 시스템 이미지를 확인하는 데 사용되는 키의 보안 해시입니다. SHA-256을 추천합니다.
deviceLocked BOOLEAN 부트로더가 잠겨 있으면 참이며 이는 서명된 이미지만 플래시될 수 있고 자체 검사 부팅 확인이 완료된 것을 의미합니다.
verifiedBootState VerifiedBootState 자체 검사 부팅 상태입니다.
verifiedBootHash OCTET_STRING 자체 검사 부팅으로 보호되는 모든 데이터의 다이제스트입니다. 자체 검사 부팅의 Android 자체 검사 부팅 구현을 사용하는 기기는 이 값에 VBMeta struct의 다이제스트 또는 자체 검사 부팅 메타데이터 구조가 포함됩니다. 이 값을 계산하는 방법에 관한 자세한 내용은 VBMeta 다이제스트를 참조하세요.

VerifiedBootState 값

verifiedBootState 값은 다음과 같은 의미를 갖습니다.

의미
Verified 부트로더에서부터 확인된 파티션으로 확장되는 신뢰할 수 있는 전체 체인을 나타내며 부트로더, 부팅 파티션 및 모든 확인된 파티션이 포함됩니다.
이 상태에서 verifiedBootKey 값은 삽입된 인증서의 해시이며 ROM에 삽입된 변경 불가능한 인증서를 의미합니다.
이 상태는 자체 검사 부팅 흐름 문서에 설명된 녹색 부팅 상태에 해당합니다.
SelfSigned 삽입된 인증서를 사용하여 부팅 파티션이 확인되었고 서명이 유효함을 나타냅니다. 부트로더는 부팅 프로세스를 계속 진행하기 전에 경고와 공개 키의 디지털 지문을 표시합니다.
이 상태에서 verifiedBootKey 값은 자체 서명 인증서의 해시입니다.
이 상태는 자체 검사 부팅 흐름 문서에 설명된 노란색 부팅 상태에 해당합니다.
Unverified 기기가 자유롭게 수정될 수 있음을 나타냅니다. 기기 무결성을 위해 사용자는 대역 외 인증을 해야 합니다. 부팅 프로세스를 계속 진행하기 전에 부트로더가 사용자에게 경고를 표시합니다.
이 상태에서 verifiedBootKey 값은 비어 있습니다.
이 상태는 자체 검사 부팅 흐름 문서에 설명된 주황색 부팅 상태에 해당합니다.
Failed 기기가 인증에 실패했음을 나타냅니다. 이 상태에서는 부트로더가 중지되므로 실제로 이 값을 포함하는 증명 인증서는 없습니다. 이 값은 완전성을 위해 여기에 포함되어 있습니다.
이 상태는 자체 검사 부팅 흐름 문서에 설명된 빨간색 부팅 상태에 해당합니다.

SecurityLevel 값

securityLevel 값은 다음과 같은 의미를 갖습니다.

의미
Software 관련 요소(증명 또는 키)를 생성하거나 관리하는 코드는 Android 시스템에 구현되며 시스템이 도용될 경우 변경될 수 있습니다.
TrustedEnvironment 관련 요소(증명 또는 키)를 생성하거나 관리하는 코드는 신뢰할 수 있는 실행 환경(TEE)에 구현됩니다. 이 코드는 TEE가 도용되면 변경될 수 있지만 TEE는 원격 도용에 매우 강하고 직접적인 하드웨어 공격으로 인한 도용에도 비교적 강합니다.
StrongBox 관련 요소(증명 또는 키)를 생성하거나 관리하는 코드는 전용 하드웨어 보안 모듈에 구현됩니다. 이 코드는 하드웨어 보안 모듈이 도용되면 변경될 수 있지만 원격 도용에 매우 강하고 직접적인 하드웨어 공격에 의한 도용에도 매우 강합니다.

고유 ID

고유 ID는 제한된 기간에만 기기를 식별하는 128비트 값입니다. 이 값은 다음을 사용하여 계산됩니다.

HMAC_SHA256(T || C || R, HBK)

여기서

  • T는 '시간 카운터 값'이며 이 값은 Tag::CREATION_DATETIME 값을 2592000000으로 나누고 나머지는 버립니다. T는 30일마다 변경됩니다(2592000000 = 30 * 24 * 60 * 60 * 1000).
  • CTag::APPLICATION_ID의 값입니다.
  • R은 attest_key 호출의 attest_params 매개변수에 Tag::RESET_SINCE_ID_ROTATION이 있으면 1이고 태그가 없으면 0입니다.
  • HBK는 신뢰할 수 있는 실행 환경(TEE)에 알려진 하드웨어에 결합된 고유한 보안 비밀이며 TEE에 의해 공개되지 않습니다. 보안 비밀은 최소 128비트의 엔트로피를 포함하며 개별 기기마다 고유합니다(128비트 엔트로피인 경우 확률적 고유성이 허용됨). HBK는 HMAC 또는 AES_CMAC를 통해 통합된 키 자료에서 파생되어야 합니다.

HMAC_SHA256 출력을 128비트로 자릅니다.

증명 키 및 인증서

두 개의 키(RSA 키 하나와 ECDSA 키 하나) 및 키에 대한 인증서 체인은 안전하게 기기에 프로비저닝됩니다.

Android 12에서는 원격 키 프로비저닝을 도입하고 Android 13에서는 기기에서 이를 구현해야 합니다. 원격 키 프로비저닝은 애플리케이션별로 ECDSA P256 증명 인증서를 현장의 기기에 제공합니다. 이러한 인증서는 팩토리에서 프로비저닝한 인증서보다 수명이 짧습니다.

ID 증명

Android 8.0은 Keymaster 3이 설치된 기기의 ID 증명을 선택적으로 지원합니다. ID 증명을 사용하면 기기에서 일련번호 또는 IMEI와 같은 하드웨어 식별자 증명을 제공할 수 있습니다. ID 증명이 선택적 기능이기는 하지만 기기의 ID를 증명할 수 있으면 트루 제로터치 원격 구성 같은 사용 사례를 사용 설정하여 안전성을 더 높일 수 있기 때문에(원격 측에서 ID를 스푸핑한 기기가 아니라 올바른 기기와 통신한다고 확신할 수 있기 때문) 모든 Keymaster 3 구현은 ID 증명을 지원하는 것이 좋습니다.

ID 증명은 기기가 공장에서 출고되기 전에 신뢰할 수 있는 실행 환경(TEE)에서만 액세스할 수 있는 기기의 하드웨어 식별자 사본을 생성하여 작동합니다. 사용자는 기기의 부트로더를 잠금 해제하고 시스템 소프트웨어 및 Android 프레임워크에서 보고한 식별자를 변경할 수 있습니다. TEE에서 보유한 식별자의 사본은 이러한 방식으로 조작될 수 없습니다. 이에 따라 기기 ID 증명은 기기의 원래 하드웨어 식별자만 증명하므로 스푸핑 시도를 방지하게 됩니다.

ID 증명의 기본 API 노출 영역은 Keymaster 2에 도입된 기존 키 증명 메커니즘을 바탕으로 이루어집니다. Keymaster가 보유한 키의 증명 인증서를 요청할 때 호출자는 기기의 하드웨어 식별자가 증명 인증서의 메타데이터에 포함되도록 요청할 수 있습니다. 키가 TEE에 유지되면 인증서는 알려진 신뢰할 수 있는 루트에 체인을 다시 연결합니다. 이러한 인증서의 수신자는 인증서와 하드웨어 식별자 같은 인증서 콘텐츠를 TEE에서 작성한 것인지 확인할 수 있습니다. 하드웨어 식별자를 증명 인증서에 포함하라는 요청을 받으면 공장에서 게재된 대로 TEE는 저장소에 보유된 식별자만 증명합니다.

저장소 속성

기기의 식별자를 보유한 저장소는 다음 속성을 포함해야 합니다.

  • 기기의 원본 식별자에서 파생된 값은 기기가 공장에서 출고되기 전에 저장소에 복사됩니다.
  • destroyAttestationIds() 메서드는 식별자에서 파생된 이 데이터 사본을 영구적으로 제거할 수 있습니다. 영구 제거는 데이터가 완전히 삭제되어 초기화 또는 기기에서 실행되는 다른 절차로 복원할 수 없는 상태를 의미합니다. 이는 사용자가 부트로더를 잠금 해제하고 시스템 소프트웨어를 변경하고 Android 프레임워크에서 반환한 식별자를 수정한 기기에 특히 중요합니다.
  • RMA 기능은 하드웨어 식별자에서 파생된 데이터의 새 사본을 생성할 수 있어야 합니다. 이렇게 하면 RMA를 통과한 기기에서 ID 증명을 다시 실행할 수 있습니다. RMA 기능에서 사용하는 메커니즘은 사용자가 스푸핑된 ID의 증명을 가져올 수 있기 때문에 사용자가 ID 증명을 직접 호출할 수 없도록 보호되어야 합니다.
  • TEE의 Keymaster가 신뢰할 수 있는 앱 외에 다른 코드는 저장소에 보관된 식별자에서 파생된 데이터를 읽을 수 없습니다.
  • 저장소는 변조 탐지가 가능합니다. 저장소의 콘텐츠가 수정되었다면 TEE는 이를 콘텐츠의 사본이 제거된 것과 동일하게 취급하고 모든 ID 증명 시도를 거부합니다. 이는 아래 설명한 대로 저장소에 서명하거나 MAC으로 구현됩니다.
  • 저장소는 원본 식별자를 보관하지 않습니다. ID 증명에는 챌린지가 포함되므로 호출자는 항상 증명할 식별자를 제공합니다. TEE는 식별자가 원래의 값과 일치하는지만 확인하면 됩니다. 값 대신 원본 값의 보안 해시를 저장하면 확인할 수 있습니다.

구조

위에 나열된 속성을 포함하는 구현을 만들려면 ID에서 파생된 값을 다음 구조 S에 저장하세요. 시스템의 일반 위치를 제외하고 기기 소유자가 루팅을 통해 수정할 수 있는 ID 값의 다른 사본은 저장하지 않습니다.

S = D || HMAC(HBK, D)

여기서

  • D = HMAC(HBK, ID1) || HMAC(HBK, ID2) || ... || HMAC(HBK, IDn)
  • HMAC는 적절한 보안 해시를 사용하는 HMAC 구조입니다(SHA-256 추천).
  • HBK는 다른 목적으로 사용되지 않는 하드웨어에 결합된 키입니다.
  • ID1...IDn은 원본 ID 값입니다. 기기마다 식별자 수가 다르므로 특정 색인에 특정 값을 연결하는 것은 구현에 따라 달라집니다.
  • ||는 연결을 나타냅니다.

HMAC 출력은 고정 크기이므로 개별 ID 해시 또는 D의 HMAC를 찾을 수 있는 헤더나 다른 구조는 필요하지 않습니다. 증명을 실행하기 위해 제공된 값을 확인하는 것 외에 수정되거나 손상된 개별 ID가 없다는 것을 확인하기 위해 구현은 S에서 D를 추출하고 HMAC(HBK, D)를 계산하고 S의 값과 비교하여 S를 확인해야 합니다. 또한 구현은 모든 개별 ID 요소와 S의 유효성을 검사하기 위해 상수 시간 비교를 사용해야 합니다. 비교 시간은 제공된 ID의 수와 테스트의 모든 부분의 정확한 일치 여부에 관계없이 일정해야 합니다.

하드웨어 식별자

ID 증명은 다음 하드웨어 식별자를 지원합니다.

  1. 브랜드 이름, Android의 Build.BRAND에서 반환함
  2. 기기 이름, Android의 Build.DEVICE에서 반환함
  3. 제품 이름, Android의 Build.PRODUCT에서 반환함
  4. 제조업체 이름, Android의 Build.MANUFACTURER에서 반환함
  5. 모델 이름, Android의 Build.MODEL에서 반환함
  6. 일련번호
  7. 모든 무선의 IMEI
  8. 모든 무선의 MEID

기기 ID 증명을 지원하기 위해 기기는 이러한 식별자를 증명합니다. Android를 실행하는 모든 기기에는 처음 6개의 식별자가 있고 이러한 식별자는 이 기능이 작동하기 위해 필요합니다. 기기에 통합된 무선 라디오가 있다면 기기는 라디오의 IMEI 및 MEID의 증명도 지원해야 합니다.

키 증명을 실행하고 증명할 기기 식별자를 요청에 포함하여 ID 증명을 요청합니다. 식별자는 다음과 같은 태그가 지정됩니다.

  • ATTESTATION_ID_BRAND
  • ATTESTATION_ID_DEVICE
  • ATTESTATION_ID_PRODUCT
  • ATTESTATION_ID_MANUFACTURER
  • ATTESTATION_ID_MODEL
  • ATTESTATION_ID_SERIAL
  • ATTESTATION_ID_IMEI
  • ATTESTATION_ID_MEID

증명할 식별자는 UTF-8로 인코딩된 바이트 문자열입니다. 이 형식은 숫자 식별자에도 적용됩니다. 증명할 각 식별자는 UTF-8로 인코딩된 문자열로 표현됩니다.

기기에서 ID 증명을 지원하지 않는다면(또는 destroyAttestationIds()가 이전에 호출되었고 기기에서 더 이상 ID를 증명할 수 없다면) 이러한 태그를 하나 이상 포함하는 키 증명 요청은 ErrorCode::CANNOT_ATTEST_IDS를 반환하며 실패합니다.

기기가 ID 증명을 지원하고 위의 태그 중 하나 이상의 태그가 키 증명 요청에 포함되어 있다면 TEE는 각 태그와 함께 제공된 식별자가 하드웨어 식별자의 사본과 일치하는지 확인합니다. 하나 이상의 식별자가 일치하지 않으면 전체 증명은 ErrorCode::CANNOT_ATTEST_IDS를 반환하며 실패합니다. 동일한 태그가 여러 번 제공되는 것은 유효합니다. 예를 들어 기기가 여러 IMEI와 함께 여러 라디오를 사용할 수 있는 경우 IMEI를 증명하는 데 유용할 수 있습니다. 증명 요청은 각 ATTESTATION_ID_IMEI와 함께 제공된 값이 기기의 라디오 중 하나와 일치한다면 유효합니다. 다른 모든 태그에도 동일하게 적용됩니다.

증명이 성공하면 증명된 ID는 위의 스키마를 사용하여 발급된 증명 인증서의 증명 확장(OID 1.3.6.1.4.1.11129.2.1.17)에 추가됩니다. Keymaster 2 증명 스키마의 변경사항은 설명과 함께 굵게 표시되어 있습니다.

자바 API

이 섹션은 정보 제공만을 목적으로 합니다. Keymaster 구현자는 자바 API를 구현하거나 사용하지 않습니다. 이 정보는 애플리케이션에서 기능을 사용하는 방법에 관해 구현자의 이해를 돕기 위해 제공됩니다. 시스템 구성요소는 이를 다르게 사용할 수 있으므로 이 섹션을 표준으로 취급해서는 안 됩니다.