키 증명으로 하드웨어 지원 키 쌍 확인

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

참고: 기기의 하드웨어 기반 키의 속성을 프로덕션 수준 환경에서 확인하려면 먼저 기기에서 하드웨어 수준 키 증명을 지원하는지 확인해야 합니다. 그렇게 하려면 증명 인증서 체인에 Google 증명 루트 키로 서명된 루트 인증서가 포함되어 있고, 키 설명 데이터 구조 내 attestationSecurityLevel 요소가 TrustedEnvironment 보안 수준으로 설정되어 있는지 확인해야 합니다.

또한 인증서 체인에 있는 서명을 확인하고 인증서 해지 상태 목록을 확인하여 체인에 해지된 키가 없는지 확인하는 것이 중요합니다. 모두 유효하며 루트가 위에 언급된 Google 루트 키인 경우가 아니면 증명을 완전히 신뢰해서는 안 됩니다. 하지만 취소된 인증서가 포함된 기기는 적어도 소프트웨어 증명만 지원하는 기기만큼 신뢰할 수 있습니다. 완전히 유효한 증명은 신뢰할 수 있음을 강력하게 알려주는 긍정 지표입니다. 유효한 증명이 하나도 없는 경우는 중립(부정적이지 않음) 지표입니다.

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

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

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

참고: 하드웨어 수준 키 증명, Android 7.0(API 레벨 24) 이상, Google Play 서비스와 함께 배송되는 기기의 루트 인증서는 Google 증명 루트 키로 서명됩니다. 이 루트 인증서가 아래 표시된 인증서인지 확인해야 합니다.

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

  1. KeyStore 개체의 getCertificateChain() 메서드를 사용하여 하드웨어 기반 키 저장소와 연결된 X.509 인증서 체인 참조를 가져옵니다.
  2. X509Certificate 개체의 checkValidity() 메서드를 사용해 각 인증서의 유효성을 확인합니다 또한 루트 인증서를 신뢰할 수 있는지 확인합니다.

    주의: 앱 내에서 이 프로세스를 직접 완료할 수 있지만 신뢰하는 별도 서버에서 인증서 해지 상태를 확인하는 것이 더 안전합니다.

  3. 신뢰하는 별도 서버에서 도구 모음에 가장 적합한 ASN.1 파서 라이브러리 참조를 가져옵니다. 이 파서를 사용해 인증서 체인의 첫 번째 요소 내에 표시되는 증명 인증서 확장 데이터를 추출합니다.

    키 증명 샘플Bouncy Castle의 ASN.1 파서를 사용해 증명 인증서의 확장 데이터를 추출합니다. 자체 파서를 만들기 위한 참조로 이 샘플을 사용할 수 있습니다.

    확장 데이터의 스키마에 관한 자세한 내용은 인증서 확장 데이터 스키마를 참조하세요.

  4. ASN.1 파서에서 가져온 확장 데이터를 하드웨어 기반 키에 포함될 것으로 예상되는 값 집합과 비교합니다.

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

루트 인증서

증명의 신뢰성은 체인의 루트 인증서에 따라 결정됩니다. Google Play를 비롯하여 Google의 앱 제품군을 보유하는 데 필요한 테스트를 통과했으며, Android 7.0(API 레벨 24) 이상이 포함되어 출시된 Android 기기는 Google 하드웨어 증명 루트 인증서로 서명된 증명 키를 사용해야 합니다. 이 인증서는 다음과 같습니다.

      -----BEGIN CERTIFICATE-----
      MIIFYDCCA0igAwIBAgIJAOj6GWMU0voYMA0GCSqGSIb3DQEBCwUAMBsxGTAXBgNV
      BAUTEGY5MjAwOWU4NTNiNmIwNDUwHhcNMTYwNTI2MTYyODUyWhcNMjYwNTI0MTYy
      ODUyWjAbMRkwFwYDVQQFExBmOTIwMDllODUzYjZiMDQ1MIICIjANBgkqhkiG9w0B
      AQEFAAOCAg8AMIICCgKCAgEAr7bHgiuxpwHsK7Qui8xUFmOr75gvMsd/dTEDDJdS
      Sxtf6An7xyqpRR90PL2abxM1dEqlXnf2tqw1Ne4Xwl5jlRfdnJLmN0pTy/4lj4/7
      tv0Sk3iiKkypnEUtR6WfMgH0QZfKHM1+di+y9TFRtv6y//0rb+T+W8a9nsNL/ggj
      nar86461qO0rOs2cXjp3kOG1FEJ5MVmFmBGtnrKpa73XpXyTqRxB/M0n1n/W9nGq
      C4FSYa04T6N5RIZGBN2z2MT5IKGbFlbC8UrW0DxW7AYImQQcHtGl/m00QLVWutHQ
      oVJYnFPlXTcHYvASLu+RhhsbDmxMgJJ0mcDpvsC4PjvB+TxywElgS70vE0XmLD+O
      JtvsBslHZvPBKCOdT0MS+tgSOIfga+z1Z1g7+DVagf7quvmag8jfPioyKvxnK/Eg
      sTUVi2ghzq8wm27ud/mIM7AY2qEORR8Go3TVB4HzWQgpZrt3i5MIlCaY504LzSRi
      igHCzAPlHws+W0rB5N+er5/2pJKnfBSDiCiFAVtCLOZ7gLiMm0jhO2B6tUXHI/+M
      RPjy02i59lINMRRev56GKtcd9qO/0kUJWdZTdA2XoS82ixPvZtXQpUpuL12ab+9E
      aDK8Z4RHJYYfCT3Q5vNAXaiWQ+8PTWm2QgBR/bkwSWc+NpUFgNPN9PvQi8WEg5Um
      AGMCAwEAAaOBpjCBozAdBgNVHQ4EFgQUNmHhAHyIBQlRi0RsR/8aTMnqTxIwHwYD
      VR0jBBgwFoAUNmHhAHyIBQlRi0RsR/8aTMnqTxIwDwYDVR0TAQH/BAUwAwEB/zAO
      BgNVHQ8BAf8EBAMCAYYwQAYDVR0fBDkwNzA1oDOgMYYvaHR0cHM6Ly9hbmRyb2lk
      Lmdvb2dsZWFwaXMuY29tL2F0dGVzdGF0aW9uL2NybC8wDQYJKoZIhvcNAQELBQAD
      ggIBACDIw41L3KlXG0aMiS//cqrG+EShHUGo8HNsw30W1kJtjn6UBwRM6jnmiwfB
      Pb8VA91chb2vssAtX2zbTvqBJ9+LBPGCdw/E53Rbf86qhxKaiAHOjpvAy5Y3m00m
      qC0w/Zwvju1twb4vhLaJ5NkUJYsUS7rmJKHHBnETLi8GFqiEsqTWpG/6ibYCv7rY
      DBJDcR9W62BW9jfIoBQcxUCUJouMPH25lLNcDc1ssqvC2v7iUgI9LeoM1sNovqPm
      QUiG9rHli1vXxzCyaMTjwftkJLkf6724DFhuKug2jITV0QkXvaJWF4nUaHOTNA4u
      JU9WDvZLI1j83A+/xnAJUucIv/zGJ1AMH2boHqF8CY16LpsYgBt6tKxxWH00XcyD
      CdW2KlBCeqbQPcsFmWyWugxdcekhYsAWyoSf818NUsZdBWBaR/OukXrNLfkQ79Iy
      ZohZbvabO/X+MVT3rriAoKc8oE2Uws6DF+60PV7/WIPjNvXySdqspImSN78mflxD
      qwLqRBYkA3I75qppLGG9rp7UCdRjxMl8ZDBld+7yvHVgt1cVzJx9xnyGCC23Uaic
      MDSXYrB4I4WHXPGjxhZuCuPBLTdOLU8YRvMYdEvYebWHMpvwGCF6bAx3JBpIeOQ1
      wDB5y0USicV3YgYGmi+NZfhA4URSh77Yd6uuJOJENRaNVTzk
      -----END CERTIFICATE-----
    

수신하는 증명 체인의 루트 인증서가 위의 인증서이고 체인에 해지된 인증서가 없는 경우 다음을 알 수 있습니다.

  1. 키가 Google에서 안전하다고 신뢰하는 하드웨어에 있습니다.
  2. 루트 인증서에 증명 인증서에서 설명한 속성이 있습니다.

증명 체인에 다른 루트 인증서가 있는 경우 Google에서는 하드웨어의 보안에 대해 어떠한 주장도 하지 않습니다. 그렇다고 해서 키가 손상되었다는 것은 아니며, 증명이 키가 안전한 하드웨어에 있음을 입증하지 못한다는 의미에 불과하므로 보안 가정을 적절하게 조정해야 합니다.

루트 인증서가 위의 인증서가 아니라면 다음 두 가지 이유가 있을 수 있습니다.

  • 가장 가능성이 높은 이유는 기기가 Android 7.0 미만 버전으로 실행되었으며, 기기에서 하드웨어 증명을 지원하지 않기 때문입니다. 이 경우 Android에 같은 종류의 증명 인증서를 생성하지만 Android 소스 코드에 하드코딩된 키로 서명된 증명 소프트웨어가 구현되어 있습니다. 이 서명 키는 비밀이 아니므로, 공격자가 안전한 하드웨어를 제공하는 것으로 가장하여 만든 증명일 수 있습니다.
  • 가능성이 있는 다른 이유는 기기가 Google Play 기기가 아니기 때문입니다. 이 경우 기기 제조업체는 자유롭게 자체 루트를 만들고 증명의 의미에 대해 어떤 주장이든 할 수 있습니다. 기기 제조업체의 문서를 참조하세요. 이 문서가 작성되는 시점에 Google은 어떤 기기 제조업체에서 이와 같은 작업을 했는지 알지 못합니다.

인증서 해지 상태 목록

증명 키는 공격자의 잘못된 처리나 의심되는 추출 등 여러 가지 이유로 해지될 수 있습니다. 따라서 증명 체인의 모든 인증서 상태를 공식 인증서 해지 상태 목록과 비교하여 확인해야 합니다. 이 목록은 Google에서 유지 관리하며 http://android.googleapis.com/attestation/status에 게시됩니다. 이 URL은 정상적인 유효 상태가 아닌 인증서의 해지 상태가 포함된 JSON 파일을 반환합니다. JSON 파일의 형식은 다음 JSON 스키마(초안 07) 정의를 따릅니다.

{
      "$schema": "http://json-schema.org/draft-07/schema#",
      "type": "object",
      "properties": {
        "entries": {
          "description" : "Each entry represents the status of an attestation key. The dictionary-key is the certificate serial number in lowercase hex.",
          "type": "object",
          "propertyNames": {
             "pattern": "^[a-f0-9]*$"
          },
          "additionalProperties": {
            "type": "object",
            "properties": {
              "status": {
                "description": "[REQUIRED] Current status of the key.",
                "type": "string",
                "enum": ["REVOKED", "SUSPENDED"]
              },
              "expires": {
                "description": "[OPTIONAL] UTC date when certificate expires in ISO8601 format (YYYY-MM-DD). Can be used to clear expired certificates from the status list.",
                "type": "string",
                "format": "date"
              },
              "reason": {
                "description": "[OPTIONAL] Reason for the current status.",
                "type": "string",
                "enum": ["UNSPECIFIED", "KEY_COMPROMISE", "CA_COMPROMISE", "SUPERSEDED", "SOFTWARE_FLAW"]
              },
              "comment": {
                "description": "[OPTIONAL] Free form comment about the key status.",
                "type": "string",
                "maxLength": 140
              }
            },
            "required": ["status"],
            "additionalProperties": false
          }
        }
      },
      "required": ["entries"],
      "additionalProperties": false
    }

다음은 인증서 해지 상태 목록의 예입니다.

{
      "entries": {
        "2c8cdddfd5e03bfc": {
          "status": "REVOKED",
          "expires": "2020-11-13",
          "reason": "KEY_COMPROMISE",
          "comment": "Key stored on unsecure system"
        },
        "c8966fcb2fbb0d7a": {
          "status": "SUSPENDED",
          "reason": "SOFTWARE_FLAW",
          "comment": "Bug in keystore causes this key malfunction b/555555"
        }
      }
    }
    

기존 CRL

기존 증명 인증서에 포함된 CRL URL은 계속 작동합니다. 새 증명 인증서에는 CRL URL 확장 프로그램이 더 이상 포함되지 않습니다. 기존 인증서 상태도 증명 상태 목록에 포함되므로 개발자가 새 인증서와 기존 인증서 모두의 증명 상태 목록을 사용하는 것으로 안전하게 전환할 수 있습니다. Android 증명 키를 올바르게 확인하는 방법에 관한 예는 키 증명 샘플에 포함되어 있습니다.

인증서 확장 데이터 스키마

키 증명은 기기의 하드웨어 기반 키 저장소의 체인에 있는 첫 번째 인증서에 나타나는 확장 데이터를 확인합니다. 인증서는 ASN.1 스키마에 따라 정보를 저장합니다. 사용 중인 증명 버전에 해당하는 스키마를 보려면 다음 스키마 목록에서 적절한 탭을 선택하세요.

버전 3

    KeyDescription ::= SEQUENCE {
        attestationVersion  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,
        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,
        trustedConfirmationRequired  [508] EXPLICIT NULL OPTIONAL,
        unlockedDeviceRequired  [509] EXPLICIT NULL OPTIONAL,
        allApplications  [600] EXPLICIT NULL OPTIONAL,
        applicationId  [601] EXPLICIT OCTET_STRING OPTIONAL,
        creationDateTime  [701] EXPLICIT INTEGER OPTIONAL,
        origin  [702] EXPLICIT INTEGER OPTIONAL,
        rootOfTrust  [704] EXPLICIT RootOfTrust OPTIONAL,
        osVersion  [705] EXPLICIT INTEGER OPTIONAL,
        osPatchLevel  [706] EXPLICIT INTEGER OPTIONAL,
        attestationApplicationId  [709] EXPLICIT OCTET_STRING OPTIONAL,
        attestationIdBrand  [710] EXPLICIT OCTET_STRING OPTIONAL,
        attestationIdDevice  [711] EXPLICIT OCTET_STRING OPTIONAL,
        attestationIdProduct  [712] EXPLICIT OCTET_STRING OPTIONAL,
        attestationIdSerial  [713] EXPLICIT OCTET_STRING OPTIONAL,
        attestationIdImei  [714] EXPLICIT OCTET_STRING OPTIONAL,
        attestationIdMeid  [715] EXPLICIT OCTET_STRING OPTIONAL,
        attestationIdManufacturer  [716] EXPLICIT OCTET_STRING OPTIONAL,
        attestationIdModel  [717] EXPLICIT OCTET_STRING OPTIONAL,
        vendorPatchLevel  [718] EXPLICIT INTEGER OPTIONAL,
        bootPatchLevel  [719] EXPLICIT INTEGER OPTIONAL,
    }

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

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

버전 2

    KeyDescription ::= SEQUENCE {
        attestationVersion  2,
        attestationSecurityLevel  SecurityLevel,
        keymasterVersion  INTEGER,
        keymasterSecurityLevel  SecurityLevel,
        attestationChallenge  OCTET_STRING,
        uniqueId  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,
        attestationApplicationId  [709] EXPLICIT OCTET_STRING OPTIONAL,
        attestationIdBrand  [710] EXPLICIT OCTET_STRING OPTIONAL,
        attestationIdDevice  [711] EXPLICIT OCTET_STRING OPTIONAL,
        attestationIdProduct  [712] EXPLICIT OCTET_STRING OPTIONAL,
        attestationIdSerial  [713] EXPLICIT OCTET_STRING OPTIONAL,
        attestationIdImei  [714] EXPLICIT OCTET_STRING OPTIONAL,
        attestationIdMeid  [715] EXPLICIT OCTET_STRING OPTIONAL,
        attestationIdManufacturer  [716] EXPLICIT OCTET_STRING OPTIONAL,
        attestationIdModel  [717] EXPLICIT OCTET_STRING OPTIONAL,
    }

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

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

버전 1

    KeyDescription ::= SEQUENCE {
        attestationVersion  1,
        attestationSecurityLevel  SecurityLevel,
        keymasterVersion  INTEGER,
        keymasterSecurityLevel  SecurityLevel,
        attestationChallenge  OCTET_STRING,
        uniqueId  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,
    }

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

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

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

KeyDescription

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

attestationVersion
키 증명 기능의 버전.
attestationSecurityLevel

증명의 보안 수준.

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

keymasterVersion
Keymaster HAL(하드웨어 추상화 계층)의 버전. 버전 0.2 또는 0.3을 나타내려면 0, 버전 1.0을 나타내려면 1, 버전 2.0을 나타내려면 2를 사용합니다.
keymasterSecurityLevel
Keymaster 구현의 보안 수준.
uniqueId
이 값은 제한된 기간에만 기기를 식별합니다. 이 값은 계산되며 시스템 앱에서만 사용합니다. 다른 모든 앱에서는 uniqueId가 비어 있습니다.
softwareEnforced
선택사항. 기기의 TEE가 아니라 Android 시스템에서 시행하는 Keymaster 승인 목록
teeEnforced
선택사항. 기기의 TEE에서 시행하는 Keymaster 승인 목록

SecurityLevel

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

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

Software
기능을 만들고 관리하는 로직이 Android 시스템에서 구현됩니다. 키 쌍을 만들고 저장하는 용도의 경우, 이 위치는 TEE보다는 덜 안전하지만 앱의 프로세스 공간보다는 더 안전합니다.
TrustedEnvironment
기능을 만들고 관리하는 로직이 안전한 하드웨어(예: TEE)에서 구현됩니다. 키 쌍을 만들고 저장하는 용도의 경우, 안전한 하드웨어는 원격 손상에 잘 견디므로 이 위치가 더 안전합니다.
StrongBox
기능을 만들고 관리하는 로직이 전용 하드웨어 보안 모듈에서 구현됩니다. 키 쌍을 만들고 저장하는 용도의 경우, 이 위치는 모듈에 대한 원격 손상 및 하드웨어 공격에 잘 견디므로 더 안전합니다.

AuthorizationList

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

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

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

purpose
태그 ID 값 1을 사용하는 Tag::PURPOSE Keymaster 승인 태그에 해당합니다.
algorithm

태그 ID 값 2를 사용하는 Tag::ALGORITHM Keymaster 승인 태그에 해당합니다.

증명 AuthorizationList 개체에서 알고리즘 값은 항상 RSA 또는 EC입니다.

keySize
태그 ID 값 3을 사용하는 Tag::KEY_SIZE Keymaster 승인 태그에 해당합니다.
digest
태그 ID 값 5를 사용하는 Tag::DIGEST Keymaster 승인 태그에 해당합니다.
padding
태그 ID 값 6을 사용하는 Tag::PADDING Keymaster 승인 태그에 해당합니다.
ecCurve

태그 ID 값 10을 사용하는 Tag::EC_CURVE Keymaster 승인 태그에 해당합니다.

Android 시스템 키 저장소에서 서명 및 확인을 위해 ECDSA를 사용하는 타원 곡선(EC) 키 쌍을 생성하는 데 사용되는 매개변수 집합입니다.

rsaPublicExponent
태그 ID 값 200을 사용하는 Tag::RSA_PUBLIC_EXPONENT Keymaster 승인 태그에 해당합니다.
rollbackResistance

키 증명 버전 3에만 있습니다.

태그 ID 값 303을 사용하는 Tag::ROLLBACK_RESISTANT Keymaster 승인 태그에 해당합니다.

activeDateTime
태그 ID 값 400을 사용하는 Tag::ACTIVE_DATETIME Keymaster 승인 태그에 해당합니다.
originationExpireDateTime
태그 ID 값 401을 사용하는 Tag::ORIGINATION_EXPIRE_DATETIME Keymaster 승인 태그에 해당합니다.
usageExpireDateTime
태그 ID 값 402를 사용하는 Tag::USAGE_EXPIRE_DATETIME Keymaster 승인 태그에 해당합니다.
noAuthRequired

태그 ID 값 503을 사용하는 Tag::NO_AUTH_REQUIRED Keymaster 승인 태그에 해당합니다.

userAuthType
태그 ID 값 504를 사용하는 Tag::USER_AUTH_TYPE Keymaster 승인 태그에 해당합니다.
authTimeout
태그 ID 값 505를 사용하는 Tag::AUTH_TIMEOUT Keymaster 승인 태그에 해당합니다.
allowWhileOnBody

태그 ID 값 506을 사용하는 Tag::ALLOW_WHILE_ON_BODY Keymaster 승인 태그에 해당합니다.

사용자가 기기를 계속 몸에 착용하고 있으면 인증 시간 제한 후 키를 사용하도록 허용합니다. 안전한 신체용 센서는 기기가 사용자의 신체에 착용 되어 있는지 확인합니다.

trustedUserPresenceRequired

키 증명 버전 3에만 있습니다.

태그 ID 값 507을 사용하는 Tag::TRUSTED_USER_PRESENCE_REQUIRED Keymaster 승인 태그에 해당합니다.

사용자가 실제 존재 증거를 제공한 경우에만 이 키를 사용할 수 있음을 지정합니다. 몇 가지 예는 다음과 같습니다.

  • StrongBox 키의 경우 하드웨어 버튼이 StrongBox 기기의 핀에 내장되어 있습니다.
  • TEE 키의 경우 TEE에서 스캐너를 독점적으로 제어하고 지문 일치 프로세스를 시행하는 한 지문 인증이 존재 증명을 제공합니다.
trustedConfirmationRequired

키 증명 버전 3에만 있습니다.

태그 ID 값 508을 사용하는 Tag::TRUSTED_CONFIRMATION_REQUIRED Keymaster 승인 태그에 해당합니다.

사용자가 승인 토큰을 사용해 서명될 데이터를 확인하는 경우에만 키를 사용할 수 있음을 지정합니다. 사용자의 확인을 받는 방법에 관한 자세한 내용은 Android 보안 확인을 참조하세요.

참고: 이 태그는 SIGN 목적으로 사용되는 키에만 적용할 수 있습니다.

unlockedDeviceRequired

키 증명 버전 3에만 있습니다.

태그 ID 값 509를 사용하는 Tag::UNLOCKED_DEVICE_REQUIRED Keymaster 승인 태그에 해당합니다.

allApplications

태그 ID 값 600을 사용하는 Tag::ALL_APPLICATIONS Keymaster 승인 태그에 해당합니다.

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

applicationId
태그 ID 값 601을 사용하는 Tag::APPLICATION_ID Keymaster 승인 태그에 해당합니다.
creationDateTime
태그 ID 값 701을 사용하는 Tag::CREATION_DATETIME Keymaster 승인 태그에 해당합니다.
origin

태그 ID 값 702를 사용하는 Tag::ORIGIN Keymaster 승인 태그에 해당합니다.

rollbackResistant

키 증명 버전 1과 2에만 있습니다.

태그 ID 값 703을 사용하는 Tag::ROLLBACK_RESISTANT Keymaster 승인 태그에 해당합니다.

rootOfTrust

태그 ID 값 704를 사용하는 Tag::ROOT_OF_TRUST Keymaster 승인 태그에 해당합니다.

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

osVersion

태그 ID 값 705를 사용하는 Tag::OS_VERSION Keymaster 승인 태그에 해당합니다.

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

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

osPatchLevel

태그 ID 값 706을 사용하는 Tag::PATCHLEVEL Keymaster 승인 태그에 해당합니다.

Keymaster에서 사용되는 보안 패치와 연관된 월과 연도로, 6자리 정수로 지정됩니다. 예를 들어, 2018년 8월 패치는 201808로 나타냅니다.

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

attestationApplicationId

키 증명 버전 2와 3에만 있습니다.

태그 ID 값 709를 사용하는 Tag::ATTESTATION_APPLICATION_ID Keymaster 승인 태그에 해당합니다.

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

attestationIdBrand

키 증명 버전 2와 3에만 있습니다.

태그 ID 값 710을 사용하는 Tag::ATTESTATION_ID_BRAND Keymaster 태그에 해당합니다.

attestationIdDevice

키 증명 버전 2와 3에만 있습니다.

태그 ID 값 711을 사용하는 Tag::ATTESTATION_ID_DEVICE Keymaster 태그에 해당합니다.

attestationIdProduct

키 증명 버전 2와 3에만 있습니다.

태그 ID 값 712를 사용하는 Tag::ATTESTATION_ID_PRODUCT Keymaster 태그에 해당합니다.

attestationIdSerial

키 증명 버전 2와 3에만 있습니다.

태그 ID 값 713을 사용하는 Tag::ATTESTATION_ID_SERIAL Keymaster 태그에 해당합니다.

attestationIdImei

키 증명 버전 2와 3에만 있습니다.

태그 ID 값 714를 사용하는 Tag::ATTESTATION_ID_IMEI Keymaster 승인 태그에 해당합니다.

attestationIdMeid

키 증명 버전 2와 3에만 있습니다.

태그 ID 값 715를 사용하는 Tag::ATTESTATION_ID_MEID Keymaster 승인 태그에 해당합니다.

attestationIdManufacturer

키 증명 버전 2와 3에만 있습니다.

태그 ID 값 716을 사용하는 Tag::ATTESTATION_ID_MANUFACTURER Keymaster 승인 태그에 해당합니다.

attestationIdModel

키 증명 버전 2와 3에만 있습니다.

태그 ID 값 717을 사용하는 Tag::ATTESTATION_ID_MODEL Keymaster 태그에 해당합니다.

vendorPatchLevel

키 증명 버전 3에만 있습니다.

태그 ID 값 718을 사용하는 Tag::VENDOR_PATCHLEVEL Keymaster 승인 태그에 해당합니다.

이 키를 사용할 기기에 설치되어야 하는 공급업체 이미지 보안 패치 수준을 지정합니다. 값은 YYYYMMDD 형식으로 표시되며, 공급업체 보안 패치의 날짜를 나타냅니다. 예를 들어 공급업체의 2018년 8월 1일 보안 패치가 설치된 Android 기기에서 키가 생성된 경우 이 값은 20180801이 됩니다.

bootPatchLevel

키 증명 버전 3에만 있습니다.

태그 ID 값 719를 사용하는 Tag::BOOT_PATCHLEVEL Keymaster 승인 태그에 해당합니다.

이 키를 사용할 기기에 설치되어야 하는 커널 이미지 보안 패치 수준을 지정합니다. 값은 YYYYMMDD 형식으로 표시되며, 시스템 보안 패치의 날짜를 나타냅니다. 예를 들어 시스템의 2018년 8월 5일 보안 패치가 설치된 Android 기기에서 키가 생성된 경우 이 값은 20180805가 됩니다.

RootOfTrust

이 값 모음은 기기 상태에 관한 키 정보를 정의합니다.

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

verifiedBootKey

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

deviceLocked
기기의 부트로더가 잠긴 경우 true이며, 이 경우 자체 검사 부팅 확인을 사용 설정하고, 서명되지 않은 기기 이미지가 기기에 플래시되지 않도록 합니다. 이 기능에 관한 자세한 내용은 자체 검사 부팅 문서를 참조하세요.
verifiedBootState
자체 검사 부팅 기능에 따른 기기의 부팅 상태
verifiedBootHash

키 증명 버전 3에만 있습니다.

자체 검사 부팅으로 보호되는 모든 데이터의 다이제스트입니다. 자체 검사 부팅의 Android 자체 검사 부팅 구현을 사용하는 기기의 경우 이 값에 VBMeta 구조체의 다이제스트 또는 자체 검사 부팅 메타데이터 구조가 포함됩니다.

이 값을 계산하는 방법에 관한 자세한 내용은 VBMeta 다이제스트를 참조하세요.

VerifiedBootState

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

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

확인됨

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

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

SelfSigned

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

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

확인되지 않음
사용자가 기기를 자유롭게 수정할 수 있음을 나타냅니다. 따라서 기기의 무결성을 확인하는 것은 사용자의 책임입니다.
실패
기기가 확인에 실패했음을 나타냅니다. 증명 인증서는 VerifiedBootState에 이 값을 사용해서는 안 됩니다.

AttestationApplicationId

이 데이터 구조는 증명 중인 비밀 키 머티리얼을 사용하도록 허용된 앱에 대한 Android 플랫폼의 신뢰를 반영합니다. 여러 패키지에서 동일한 UID를 공유하는 경우에만 ID가 여러 패키지로 구성될 수 있습니다. 옥텟 문자열 자체는 다음 ASN.1 스키마에 따라 형식이 지정됩니다.

    AttestationApplicationId ::= SEQUENCE {
        package_infos  SET OF AttestationPackageInfo,
        signature_digests  SET OF OCTET_STRING,
    }

    AttestationPackageInfo ::= SEQUENCE {
        package_name  OCTET_STRING,
        version  INTEGER,
    }
package_infos
AttestationPackageInfo 개체의 집합으로, 각 패키지의 이름과 버전 번호를 제공합니다.
signature_digests

getPackageInfo() 호출 시 반환되는 PackageInfosignatures 필드에 포함된 앱 서명 blob의 SHA-256 다이제스트 집합입니다. 다음 코드 스니펫에서는 예제 집합을 보여줍니다.

    {SHA256(PackageInfo.signature[0]), SHA256(PackageInfo.signature[1]), ...}