콘텐츠로 건너뛰기

자주 방문한 페이지

최근 방문한 페이지

navigation

Key Attestation

Key Attestation은 여러분이 앱에서 사용하는 키가 기기의 하드웨어 기반 키스토어에 저장되도록 보장합니다. 다음 섹션에서는 하드웨어 기반 키의 속성을 확인하는 방법과 증명 인증서 확장 데이터의 스키마를 해석하는 방법에 대해 설명합니다.

참고: Android 7.0(API 레벨 24)이 실행되는 기기 중에서 하드웨어 레벨 키 증명을 지원하는 기기는 매우 적습니다. Android 7.0이 실행되는 기타 모든 기기는 그 대신 소프트웨어 레벨 키 증명을 사용합니다. 기기의 하드웨어 기반 키의 속성을 프로덕션 레벨 환경에서 확인하려면 그 전에, 이 기기가 하드웨어 레벨 키 증명을 지원하는지 확인해야 합니다. 그러기 위해서는, Google 증명 루트 키에 의해 서명된 루트 인증서가 증명 인증서 체인에 포함되어 있는지 확인해야 하며, 또한 키 설명 데이터 구조 내의 attestationSecurityLevel 요소가 TrustedEnvironment 보안 레벨로 설정되어 있는지 확인해야 합니다.

하드웨어 기반 키 쌍 검색 및 확인

키 증명 중에 키 쌍의 별칭을 지정합니다. 그러면 증명 도구가 인증서 체인을 제공하며, 이 체인을 사용하여 키 쌍의 속성을 확인할 수 있습니다.

기기가 하드웨어 레벨 키 증명을 지원하는 경우, 이 체인 내의 루트 인증서는 증명 루트 키를 사용하여 서명됩니다. 이 루트 키는 기기 제조업체가 공장에서 기기의 하드웨어 기반 키스토어에 주입하는 것입니다.

참고: 하드웨어 레벨 키 증명, Android 7.0(API 레벨 24) 및 Google Play 서비스가 함께 제공되는 기기에서는 루트 인증서가 Google 증명 루트 키에 의해 서명됩니다. 이 루트 인증서가 Google의 루트 인증서 목록에 나타나는지 확인해야 합니다.

키 증명을 구현하려면 다음 단계를 완료해야 합니다.

  1. KeyStore 객체의 getCertificateChain() 메서드를 사용하여, 하드웨어 기반 키스토어와 연관된 X.509 인증서 체인에 대한 참조를 가져옵니다.
  2. CRL 객체의 isRevoked() 메서드를 사용하여 각 인증서의 유효성을 확인합니다.

    주의: 이 과정을 여러분의 앱 내에서 직접 완료할 수도 있지만, 여러분이 신뢰하는 별도 서버에서 인증서의 취소 목록을 확인하는 것이 더 안전한 방법입니다.

  3. Attestation 객체를 만들고, 인증서 체인의 첫 번째 요소를 인수로 전달합니다.

    // "certificates" contains the certificate chain associated with a specific key
    // pair in the device's hardware-backed keystore.
    X509Certificate attestationCert = (X509Certificate) certificates[0];
    Attestation hardwareKeyAttestation = new Attestation(attestationCert);
    

    증명 객체는 이 인증서 내의 확장 데이터를 추출하고, 보다 액세스가 용이한 형식으로 이 정보를 저장합니다. 확장 데이터의 스키마에 대한 자세한 내용은 인증서 확장 데이터 스키마를 참조하세요.

  4. Attestation 클래스 내의 Accessor 메서드를 사용하여 인증서로부터 확장 데이터를 검색합니다. 이 메서드는 인증서 확장 데이터 스키마에서와 동일한 이름과 계층 구조를 사용합니다.

    예를 들어, 기기의 TEE에 대해 확인된 부트 키를 보려면, 다음과 같은 메서드 시퀀스를 사용합니다.

    // "hardwareKeyAttestation" contains the first element of the attestation
    // certificate chain.
    AuthorizationList teeAuthList = hardwareKeyAttestation.getTeeEnforced();
    RootOfTrust teeRootOfTrust = teeAuthList.getRootOfTrust();
    byte[] teeVerifiedBootKey = teeRootOfTrust.getVerifiedBootKey();
    
  5. Attestation 객체의 확장 데이터와 하드웨어 기반 키에 포함되어야 하는 값 세트를 비교합니다.

    주의: 이 과정을 여러분의 앱 내에서 직접 완료할 수도 있지만, 여러분이 신뢰하는 별도 서버에서 인증서의 확장 데이터를 확인하는 것이 더 안전한 방법입니다.

인증서 확장 데이터 스키마

키 증명에서는 기기의 하드웨어 기반 키스토어에서 체인 내의 첫 번째 인증서에 나타나는 확장 데이터를 확인합니다. 이 인증서는 다음과 같은 ASN.1 스키마에 따라 정보를 저장합니다.

KeyDescription ::= SEQUENCE {
    attestationVersion  INTEGER,
    attestationSecurityLevel  SecurityLevel,
    keymasterVersion  INTEGER,
    keymasterSecurityLevel  SecurityLevel,
    attestationChallenge  OCTET_STRING,
    reserved  OCTET_STRING,
    softwareEnforced  AuthorizationList,
    teeEnforced  AuthorizationList,
}

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

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,
    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,
    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,
    rootOfTrust  [704] EXPLICIT RootOfTrust OPTIONAL,
    osVersion  [705] EXPLICIT INTEGER OPTIONAL,
    osPatchLevel  [706] EXPLICIT INTEGER OPTIONAL,
    attestationChallenge  [708] EXPLICIT INTEGER OPTIONAL,
    attestationApplicationId  [709] EXPLICIT OCTET_STRING OPTIONAL,
}

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

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

다음 목록은 스키마 내의 각 요소에 대한 설명을 나타냅니다.

KeyDescription

이 값 시퀀스에서는 키 증명을 통해 확인되는 키 쌍에 대한 일반적인 정보를 표시하며, 추가적인 정보에 쉽게 액세스할 수 있습니다.

attestationVersion
키 증명 기능의 버전. 1로 설정되어야 합니다.
attestationSecurityLevel

증명의 보안 레벨.

경고: Android 시스템에 저장된 키를 증명하는 것은 가능하겠지만, attestationSecurityLevel 값이 Software로 설정된 경우, Android 시스템이 손상된 경우에는 이러한 증명을 신뢰할 수 없습니다.

keymasterVersion
Keymaster HAL(하드웨어 추상화 계층)의 버전. 버전 0.2 또는 0.3을 나타내려면 0, 버전 1.0을 나타내려면 1, 버전 2.0을 나타내려면 2를 사용합니다.
keymasterSecurityLevel
Keymaster 구현의 보안 레벨.
attestationChallenge
키 증명을 사용하여 확인되는 키 쌍과 연관된 챌린지 문자열.
reserved
시스템 앱에서만 이 값을 사용합니다. 기타 모든 앱에서는 이 값이 비어 있습니다.
softwareEnforced
선택 항목. 기기의 TEE에 의해서가 아니라 Android 시스템에 의해 시행되는 Keymaster 승인 목록.
teeEnforced
선택 항목. 기기의 TEE에 의해 시행되는 Keymaster 승인 목록.

SecurityLevel

이 데이터 구조는 기기 내의 위치에 따라 소프트웨어 기능(예: 키 쌍)이 보호되는 정도를 나타냅니다.

이 데이터 구조는 열거형이므로, 정확히 다음 값 중 하나를 취합니다.

Software
Android 시스템에서 기능 생성과 관리를 구현하기 위한 로직입니다. 키 쌍을 만들고 저장하는 용도의 경우, 이 위치는 TEE보다는 덜 안전하지만 여러분의 앱의 프로세스 공간보다는 더 안전합니다.
TrustedEnvironment
보안 하드웨어(예: TEE)에서 기능 생성과 관리를 구현하기 위한 로직입니다. 키 쌍을 만들고 저장하는 용도의 경우, 이 위치가 더 안전한데, 그 이유는 보안 하드웨어가 원격 손상에 잘 견디기 때문입니다.

AuthorizationList

이 데이터 구조에는 Keymaster HAL(하드웨어 추상화 계층)에 정의된 키 쌍의 속성 자체가 포함됩니다. 이 값을 기기의 현재 상태와 비교하거나 예상되는 값 세트와 비교하여, 여러분의 앱에 사용하기에 키 쌍이 유효한지 확인할 수 있습니다.

각 필드 이름은 유사한 이름의 Keymaster 태그에 해당합니다. 예를 들어, 승인 목록의 keySize 필드는 KM_TAG_KEY_SIZE Keymaster 태그에 해당합니다.

다음 목록의 각 필드는 선택 항목입니다.

purpose
KM_TAG_PURPOSE Keymaster 태그에 해당, 태그 ID 값 1을 사용.
algorithm

KM_TAG_ALGORITHM Keymaster 태그에 해당, 태그 ID 값 2를 사용.

AuthorizationList 객체가 키 증명과 연관된 경우, 이 값은 항상 KM_ALGORITHM_RSA 또는 KM_ALGORITHM_EC입니다.

keySize
KM_TAG_KEY_SIZE Keymaster 태그에 해당, 태그 ID 값 3을 사용.
digest
KM_TAG_DIGEST Keymaster 태그에 해당, 태그 ID 값 5를 사용.
padding
KM_TAG_PADDING Keymaster 태그에 해당, 태그 ID 값 6을 사용.
ecCurve

KM_TAG_EC_CURVE Keymaster 태그에 해당, 태그 ID 값 10을 사용.

타원 곡선(EC) 키 쌍을 생성하는 데 사용되는 매개변수 세트로, Android 시스템 키스토어 내에서 서명 및 확인을 위해 ECDSA를 사용합니다.

rsaPublicExponent
KM_TAG_RSA_PUBLIC_EXPONENT Keymaster 태그에 해당, 태그 ID 값 200을 사용.
activeDateTime
KM_TAG_ACTIVE_DATETIME Keymaster 태그에 해당, 태그 ID 값 400을 사용.
originationExpireDateTime
KM_TAG_ORIGINATION_EXPIRE_DATETIME Keymaster 태그에 해당, 태그 ID 값 401을 사용.
usageExpireDateTime
KM_TAG_USAGE_EXPIRE_DATETIME Keymaster 태그에 해당, 태그 ID 값 402를 사용.
noAuthRequired

KM_TAG_NO_AUTH_REQUIRED Keymaster 태그에 해당, 태그 ID 값 503을 사용.

AuthorizationList 객체가 키 증명과 연관된 경우, 이 값은 항상 true입니다.

userAuthType
KM_TAG_USER_AUTH_TYPE Keymaster 태그에 해당, 태그 ID 값 504를 사용.
authTimeout
KM_TAG_AUTH_TIMEOUT Keymaster 태그에 해당, 태그 ID 값 505를 사용.
allowWhileOnBody

KM_TAG_ALLOW_WHILE_ON_BODY Keymaster 태그에 해당, 태그 ID 값 506을 사용.

사용자가 여전히 신체에 기기를 착용 중인 경우, 인증 제한 시간 후에 키를 사용하도록 허용합니다. 참고로, 보안 신체용 센서는 기기가 사용자의 신체에 착용 중인지 여부를 결정합니다.

AuthorizationList 객체가 키 증명과 연관된 경우, 이 값은 항상 true입니다.

allApplications

KM_TAG_ALL_APPLICATIONS Keymaster 태그에 해당, 태그 ID 값 600을 사용.

기기의 모든 앱이 키 쌍에 액세스할 수 있는지 여부를 나타냅니다.

AuthorizationList 객체가 키 증명과 연관된 경우, 이 값은 항상 true입니다.

applicationId
KM_TAG_APPLICATION_ID Keymaster 태그에 해당, 태그 ID 값 601을 사용.
creationDateTime
KM_TAG_CREATION_DATETIME Keymaster 태그에 해당, 태그 ID 값 701을 사용.
origin

KM_TAG_ORIGIN Keymaster 태그에 해당, 태그 ID 값 702를 사용.

AuthorizationList 객체가 키 증명과 연관된 경우, 이 값은 일반적으로 KM_ORIGIN_GENERATED로 설정됩니다. 증명에서 Keymaster 버전 0.2 또는 0.3을 사용하는 경우에는, 그 대신 origin이 KM_ORIGIN_UNKNOWN으로 설정될 수도 있습니다.

rollbackResistant
KM_TAG_ROLLBACK_RESISTANT Keymaster 태그에 해당, 태그 ID 값 703을 사용.
rootOfTrust

KM_TAG_ROOT_OF_TRUST Keymaster 태그에 해당, 태그 ID 값 704를 사용.

자세한 내용은, RootOfTrust 데이터 구조를 설명하는 섹션을 참조하세요.

osVersion

KM_TAG_OS_VERSION Keymaster 태그에 해당, 태그 ID 값 705를 사용.

Keymaster와 연관된 Android 운영 체제의 버전이며, 6자리 정수로 지정됩니다. 예를 들어, 버전 6.0.1은 060001로 나타냅니다.

Keymaster 버전 1.0 이상에서만 이 값을 승인 목록에 포함합니다.

osPatchLevel

KM_TAG_PATCHLEVEL Keymaster 태그에 해당, 태그 ID 값 706을 사용.

Keymaster 내에 사용 중인 보안 패치와 연관된 연도와 월로, 6자리 정수로 지정됩니다. 예를 들어, 2016년 7월 패치는 201606으로 나타냅니다.

Keymaster 버전 1.0 이상에서만 이 값을 승인 목록에 포함합니다.

attestationChallenge

KM_TAG_ATTESTATION_CHALLENGE Keymaster 태그에 해당, 태그 ID 값 708을 사용.

Keymaster에 정의된 키 쌍과 연관된 챌린지 문자열.

attestationApplicationId

KM_TAG_ATTESTATION_APPLICATION_ID Keymaster 태그에 해당, 태그 ID 값 709를 사용.

Keymaster에 있는 키 쌍을 서명한 증명 인증서의 고유 ID.

RootOfTrust

이 값 집합은 기기 상태에 대한 키 정보를 정의합니다.

다음 목록의 각 필드는 필수입니다.

verifiedBootKey

시스템 이미지를 확인하는 키의 보안 해시. 이 해시에 SHA-256 알고리즘을 사용하는 것이 좋습니다.

deviceLocked
기기의 부트로더가 잠긴 경우 true이며, 이 경우 '확인된 부팅' 검사를 활성화하고, 미서명된 기기 이미지가 기기에 플래시되는 것을 방지합니다. 이 기능에 대한 자세한 내용은 부팅 확인 문서를 참조하세요.
verifiedBootState
'확인된 부팅' 기능에 따른 기기의 부팅 상태.
osVersion
기기에서 Android 운영 체제의 현재 버전이며, 6자리 정수로 지정됩니다. 예를 들어, 버전 6.0.1은 060001로 나타냅니다.
patchMonthYear
기기에 현재 설치된 보안 패치와 연관된 연도와 월로, 6자리 정수로 지정됩니다. 예를 들어, 2016년 8월 패치는 201608로 나타냅니다.

VerifiedBootState

이 데이터 구조는 기기의 현재 부팅 상태를 제공하며, 이는 기기 부팅 완료된 후에 사용자와 앱에 제공되는 보호 레벨을 나타냅니다. 이 기능에 대한 자세한 내용은, 부팅 확인 문서 내의 부팅 상태 섹션을 참조하세요.

이 데이터 구조는 열거형이므로, 정확히 다음 값 중 하나를 취합니다.

Verified

신뢰할 수 있는 전체 체인을 나타내며 여기에는 부트로더, 부트 파티션 및 확인된 모든 파티션이 포함됩니다.

기기가 이 부팅 상태에 있으면, verifiedBootKey는 기기에 삽입된 인증서의 해시이며, 이것은 공장에서 기기 제조업체가 기기의 ROM에 추가하는 것입니다.

SelfSigned

기기에 삽입된 인증서가 기기의 부트 파티션을 확인했고 서명이 유효함을 나타냅니다.

기기가 이 부팅 상태에 있으면, verifiedBootKey는 사용자가 설치한 인증서의 해시이며, 이것은 제조업체가 제공한 원본 부트 파티션 대신에 사용자가 기기에 추가한 부트 파티션을 서명합니다.

Unverified
사용자가 기기를 자유롭게 수정할 수 있음을 나타냅니다. 따라서 사용자는 기기의 무결성을 확인할 책임이 있습니다.
Failed
기기가 확인에 실패했음을 나타냅니다. 증명 인증서는 절대 이 값을 VerifiedBootState에 사용해서는 안 됩니다.
이 사이트는 쿠키를 사용하여 사이트별 언어 및 표시 옵션에 대한 환경설정을 저장합니다.

Google Play에서 성공을 거두는 데 도움이 되는 최신 Android 개발자 뉴스 및 도움말을 받아 보세요.

* 필수 입력란

완료되었습니다.

WeChat에서 Google Developers 팔로우하기

이 사이트를 (으)로 탐색할까요?

페이지를 요청했지만 이 사이트의 언어 환경설정은 입니다.

언어 환경설정을 변경하고 이 사이트를 (으)로 탐색할까요? 언어 환경설정을 나중에 변경하려면 각 페이지 하단의 언어 메뉴를 사용하세요.

이 클래스를 사용하려면 API 수준 이상이 필요합니다.

문서에 대해 선택한 API 수준이 이므로 이 문서가 표시되지 않습니다. 왼쪽 탐색 메뉴의 선택기로 문서 API 수준을 변경할 수 있습니다.

앱에 필요한 API 수준 지정에 관한 자세한 내용은 다양한 플랫폼 버전 지원을 참조하세요.

Take a short survey?
Help us improve the Android developer experience. (April 2018 — Developer Survey)