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

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

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

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

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

키 증명 중에 키 쌍의 별칭을 지정하고 인증서 체인을 가져올 수 있습니다. 이 체인은 키 쌍의 속성을 확인하는 데 사용할 수 있습니다.

기기에서 하드웨어 수준 키 증명을 지원하는 경우 이 체인 내의 루트 인증서는 기기의 하드웨어 지원 키 저장소에 안전하게 프로비저닝된 증명 루트 키를 사용하여 서명됩니다.

참고: 하드웨어 수준 키 증명, Android 7.0(API 수준 24) 이상, Google Play 서비스와 함께 제공되는 기기의 루트 인증서는 Google 증명 루트 키로 서명됩니다. 이 루트 인증서가 루트 인증서의 섹션에 나와 있는 인증서 중 하나인지 확인합니다.

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

  1. KeyStore 객체의 getCertificateChain() 메서드를 사용하여 하드웨어 기반 키 저장소와 연결된 X.509 인증서 체인의 참조를 가져옵니다.
  2. 인증에 신뢰할 수 있는 별도의 서버로 인증서를 전송합니다.

    주의: 키 저장소와 동일한 기기에서 다음 인증 프로세스를 완료하지 마세요. 해당 기기의 Android 시스템이 손상되면 인증 프로세스에서 신뢰할 수 없는 항목이 신뢰될 수 있습니다.

  3. 도구 모음에 가장 적합한 X.509 인증서 체인 파싱 및 유효성 검사 라이브러리에 대한 참조를 가져옵니다. 루트 공개 인증서를 신뢰할 수 있고 각 인증서가 체인의 그다음 인증서에 서명하는지 확인합니다.

  4. 각 인증서의 취소 상태를 확인하여 취소된 인증서가 없는지 확인합니다.

  5. 필요한 경우 최신 인증서 체인에만 있는 프로비저닝 정보 인증서 확장을 검사합니다.

    도구 모음에 가장 적합한 CBOR 파서 라이브러리에 대한 참조를 가져옵니다. 프로비저닝 정보 인증서 확장이 포함된 루트에 가장 가까운 인증서를 찾습니다. 파서를 사용하여 해당 인증서에서 프로비저닝 정보 인증서 확장 데이터를 추출합니다.

    자세한 내용은 프로비저닝 정보 확장 데이터 스키마 섹션을 참고하세요.

  6. 도구 모음에 가장 적합한 ASN.1 파서 라이브러리에 대한 참조를 가져옵니다. 키 증명 인증서 확장 프로그램이 포함된 루트에 가장 가까운 인증서를 찾습니다. 프로비저닝 정보 인증서 확장이 있는 경우 키 증명 인증서 확장이 바로 이후의 인증서에 있어야 합니다. 파서를 사용하여 해당 인증서에서 키 증명 인증서 확장 프로그램 데이터를 추출합니다.

    주의: 키 증명 인증서 확장이 체인의 리프 인증서에 있다고 가정해서는 안 됩니다. 체인에서 처음 발견된 확장만 신뢰할 수 있습니다. 그 외 확장은 보안 하드웨어에서 발급된 것이 아니며, 공격자가 신뢰할 수 없는 키의 가짜 증명을 만들려고 할 때 체인을 확장함으로써 발급되었을 수 있습니다.

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

    자세한 내용은 키 증명 확장 프로그램 데이터 스키마 섹션을 참고하세요.

  7. 이전 단계에서 가져온 확장 데이터의 일관성을 확인하고 하드웨어 지원 키에 포함될 것으로 예상되는 값 집합과 비교합니다.

루트 인증서

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

  -----BEGIN PUBLIC KEY-----
  MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAr7bHgiuxpwHsK7Qui8xU
  FmOr75gvMsd/dTEDDJdSSxtf6An7xyqpRR90PL2abxM1dEqlXnf2tqw1Ne4Xwl5j
  lRfdnJLmN0pTy/4lj4/7tv0Sk3iiKkypnEUtR6WfMgH0QZfKHM1+di+y9TFRtv6y
  //0rb+T+W8a9nsNL/ggjnar86461qO0rOs2cXjp3kOG1FEJ5MVmFmBGtnrKpa73X
  pXyTqRxB/M0n1n/W9nGqC4FSYa04T6N5RIZGBN2z2MT5IKGbFlbC8UrW0DxW7AYI
  mQQcHtGl/m00QLVWutHQoVJYnFPlXTcHYvASLu+RhhsbDmxMgJJ0mcDpvsC4PjvB
  +TxywElgS70vE0XmLD+OJtvsBslHZvPBKCOdT0MS+tgSOIfga+z1Z1g7+DVagf7q
  uvmag8jfPioyKvxnK/EgsTUVi2ghzq8wm27ud/mIM7AY2qEORR8Go3TVB4HzWQgp
  Zrt3i5MIlCaY504LzSRiigHCzAPlHws+W0rB5N+er5/2pJKnfBSDiCiFAVtCLOZ7
  gLiMm0jhO2B6tUXHI/+MRPjy02i59lINMRRev56GKtcd9qO/0kUJWdZTdA2XoS82
  ixPvZtXQpUpuL12ab+9EaDK8Z4RHJYYfCT3Q5vNAXaiWQ+8PTWm2QgBR/bkwSWc+
  NpUFgNPN9PvQi8WEg5UmAGMCAwEAAQ==
  -----END PUBLIC KEY-----
이전에 발급된 루트 인증서
    -----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-----
  
    -----BEGIN CERTIFICATE-----
    MIIFHDCCAwSgAwIBAgIJANUP8luj8tazMA0GCSqGSIb3DQEBCwUAMBsxGTAXBgNV
    BAUTEGY5MjAwOWU4NTNiNmIwNDUwHhcNMTkxMTIyMjAzNzU4WhcNMzQxMTE4MjAz
    NzU4WjAbMRkwFwYDVQQFExBmOTIwMDllODUzYjZiMDQ1MIICIjANBgkqhkiG9w0B
    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
    AGMCAwEAAaNjMGEwHQYDVR0OBBYEFDZh4QB8iAUJUYtEbEf/GkzJ6k8SMB8GA1Ud
    IwQYMBaAFDZh4QB8iAUJUYtEbEf/GkzJ6k8SMA8GA1UdEwEB/wQFMAMBAf8wDgYD
    VR0PAQH/BAQDAgIEMA0GCSqGSIb3DQEBCwUAA4ICAQBOMaBc8oumXb2voc7XCWnu
    XKhBBK3e2KMGz39t7lA3XXRe2ZLLAkLM5y3J7tURkf5a1SutfdOyXAmeE6SRo83U
    h6WszodmMkxK5GM4JGrnt4pBisu5igXEydaW7qq2CdC6DOGjG+mEkN8/TA6p3cno
    L/sPyz6evdjLlSeJ8rFBH6xWyIZCbrcpYEJzXaUOEaxxXxgYz5/cTiVKN2M1G2ok
    QBUIYSY6bjEL4aUN5cfo7ogP3UvliEo3Eo0YgwuzR2v0KR6C1cZqZJSTnghIC/vA
    D32KdNQ+c3N+vl2OTsUVMC1GiWkngNx1OO1+kXW+YTnnTUOtOIswUP/Vqd5SYgAI
    mMAfY8U9/iIgkQj6T2W6FsScy94IN9fFhE1UtzmLoBIuUFsVXJMTz+Jucth+IqoW
    Fua9v1R93/k98p41pjtFX+H8DslVgfP097vju4KDlqN64xV1grw3ZLl4CiOe/A91
    oeLm2UHOq6wn3esB4r2EIQKb6jTVGu5sYCcdWpXr0AUVqcABPdgL+H7qJguBw09o
    jm6xNIrw2OocrDKsudk/okr/AwqEyPKw9WnMlQgLIKw1rODG2NvU9oR3GVGdMkUB
    ZutL8VuFkERQGt6vQ2OCw0sV47VMkuYbacK/xyZFiRcrPJPb41zgbQj9XAEyLKCH
    ex0SdDrx+tWUDqG8At2JHA==
    -----END CERTIFICATE-----
  
    -----BEGIN CERTIFICATE-----
    MIIFHDCCAwSgAwIBAgIJAMNrfES5rhgxMA0GCSqGSIb3DQEBCwUAMBsxGTAXBgNV
    BAUTEGY5MjAwOWU4NTNiNmIwNDUwHhcNMjExMTE3MjMxMDQyWhcNMzYxMTEzMjMx
    MDQyWjAbMRkwFwYDVQQFExBmOTIwMDllODUzYjZiMDQ1MIICIjANBgkqhkiG9w0B
    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
    AGMCAwEAAaNjMGEwHQYDVR0OBBYEFDZh4QB8iAUJUYtEbEf/GkzJ6k8SMB8GA1Ud
    IwQYMBaAFDZh4QB8iAUJUYtEbEf/GkzJ6k8SMA8GA1UdEwEB/wQFMAMBAf8wDgYD
    VR0PAQH/BAQDAgIEMA0GCSqGSIb3DQEBCwUAA4ICAQBTNNZe5cuf8oiq+jV0itTG
    zWVhSTjOBEk2FQvh11J3o3lna0o7rd8RFHnN00q4hi6TapFhh4qaw/iG6Xg+xOan
    63niLWIC5GOPFgPeYXM9+nBb3zZzC8ABypYuCusWCmt6Tn3+Pjbz3MTVhRGXuT/T
    QH4KGFY4PhvzAyXwdjTOCXID+aHud4RLcSySr0Fq/L+R8TWalvM1wJJPhyRjqRCJ
    erGtfBagiALzvhnmY7U1qFcS0NCnKjoO7oFedKdWlZz0YAfu3aGCJd4KHT0MsGiL
    Zez9WP81xYSrKMNEsDK+zK5fVzw6jA7cxmpXcARTnmAuGUeI7VVDhDzKeVOctf3a
    0qQLwC+d0+xrETZ4r2fRGNw2YEs2W8Qj6oDcfPvq9JySe7pJ6wcHnl5EZ0lwc4xH
    7Y4Dx9RA1JlfooLMw3tOdJZH0enxPXaydfAD3YifeZpFaUzicHeLzVJLt9dvGB0b
    HQLE4+EqKFgOZv2EoP686DQqbVS1u+9k0p2xbMA105TBIk7npraa8VM0fnrRKi7w
    lZKwdH+aNAyhbXRW9xsnODJ+g8eF452zvbiKKngEKirK5LGieoXBX7tZ9D1GNBH2
    Ob3bKOwwIWdEFle/YF/h6zWgdeoaNGDqVBrLr2+0DtWoiB1aDEjLWl9FmyIUyUm7
    mD/vFDkzF+wm7cyWpQpCVQ==
    -----END CERTIFICATE-----
  
    -----BEGIN CERTIFICATE-----
    MIIFHDCCAwSgAwIBAgIJAPHBcqaZ6vUdMA0GCSqGSIb3DQEBCwUAMBsxGTAXBgNV
    BAUTEGY5MjAwOWU4NTNiNmIwNDUwHhcNMjIwMzIwMTgwNzQ4WhcNNDIwMzE1MTgw
    NzQ4WjAbMRkwFwYDVQQFExBmOTIwMDllODUzYjZiMDQ1MIICIjANBgkqhkiG9w0B
    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
    AGMCAwEAAaNjMGEwHQYDVR0OBBYEFDZh4QB8iAUJUYtEbEf/GkzJ6k8SMB8GA1Ud
    IwQYMBaAFDZh4QB8iAUJUYtEbEf/GkzJ6k8SMA8GA1UdEwEB/wQFMAMBAf8wDgYD
    VR0PAQH/BAQDAgIEMA0GCSqGSIb3DQEBCwUAA4ICAQB8cMqTllHc8U+qCrOlg3H7
    174lmaCsbo/bJ0C17JEgMLb4kvrqsXZs01U3mB/qABg/1t5Pd5AORHARs1hhqGIC
    W/nKMav574f9rZN4PC2ZlufGXb7sIdJpGiO9ctRhiLuYuly10JccUZGEHpHSYM2G
    tkgYbZba6lsCPYAAP83cyDV+1aOkTf1RCp/lM0PKvmxYN10RYsK631jrleGdcdkx
    oSK//mSQbgcWnmAEZrzHoF1/0gso1HZgIn0YLzVhLSA/iXCX4QT2h3J5z3znluKG
    1nv8NQdxei2DIIhASWfu804CA96cQKTTlaae2fweqXjdN1/v2nqOhngNyz1361mF
    mr4XmaKH/ItTwOe72NI9ZcwS1lVaCvsIkTDCEXdm9rCNPAY10iTunIHFXRh+7KPz
    lHGewCq/8TOohBRn0/NNfh7uRslOSZ/xKbN9tMBtw37Z8d2vvnXq/YWdsm1+JLVw
    n6yYD/yacNJBlwpddla8eaVMjsF6nBnIgQOf9zKSe06nSTqvgwUHosgOECZJZ1Eu
    zbH4yswbt02tKtKEFhx+v+OTge/06V+jGsqTWLsfrOCNLuA8H++z+pUENmpqnnHo
    vaI47gC+TNpkgYGkkBT6B/m/U01BuOBBTzhIlMEZq9qkDWuM2cA5kW5V3FJUcfHn
    w1IdYIg2Wxg7yHcQZemFQg==
    -----END CERTIFICATE-----
  

수신하는 증명 체인의 루트 인증서에 이 공개 키가 포함되어 있고 체인에 취소된 인증서가 없는 경우 다음을 알 수 있습니다.

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

증명 체인에 다른 루트 공개 키가 있는 경우 Google에서는 하드웨어의 보안에 대해 어떠한 주장도 하지 않습니다. 이는 키가 손상되었다는 의미는 아니며, 증명이 있다고 하더라도 키가 보안 하드웨어에 있음을 입증하지는 않는다는 뜻입니다. 그에 맞게 보안 가정을 조정하세요.

루트 인증서에 이 페이지의 공개 키가 포함되지 않은 경우 다음 두 가지 이유가 있을 수 있습니다.

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

인증서 취소 상태 목록

증명 키는 잘못된 처리나 공격자의 의심되는 추출 등 여러 가지 이유로 취소될 수 있습니다. 따라서 증명 체인의 각 인증서 상태를 공식 인증서 취소 상태 목록(CRL)과 비교하여 확인해야 합니다. 이 목록은 Google에서 관리하며 https://android.googleapis.com/attestation/status에 게시됩니다. HTTP 응답의 Cache-Control 헤더가 업데이트 확인 빈도를 결정하므로 검증되는 모든 인증서에 네트워크 요청이 필요하지는 않습니다. 이 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-f1-9][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
}

CRL 예:

{
  "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 증명 키를 제대로 확인하는 방법에 관한 예는 키 증명 샘플에 포함되어 있습니다.

키 증명 확장 데이터 스키마

키 증명 확장에는 OID 1.3.6.1.4.1.11129.2.1.17이 있습니다. 확장은 ASN.1 스키마에 따라 정보를 저장합니다. 사용 중인 증명 버전에 해당하는 스키마를 보려면 다음 스키마 목록에서 적절한 탭을 선택하세요.

버전 200

KeyDescription ::= SEQUENCE {
    attestationVersion  200,
    attestationSecurityLevel  SecurityLevel,
    keyMintVersion  INTEGER,
    keyMintSecurityLevel  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,
    mgfDigest  [203] EXPLICIT SET OF INTEGER OPTIONAL,
    rollbackResistance  [303] EXPLICIT NULL OPTIONAL,
    earlyBootOnly  [305] EXPLICIT NULL OPTIONAL,
    activeDateTime  [400] EXPLICIT INTEGER OPTIONAL,
    originationExpireDateTime  [401] EXPLICIT INTEGER OPTIONAL,
    usageExpireDateTime  [402] EXPLICIT INTEGER OPTIONAL,
    usageCountLimit  [405] 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,
    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,
    deviceUniqueAttestation  [720] EXPLICIT NULL OPTIONAL,
}

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

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

버전 100

KeyDescription ::= SEQUENCE {
    attestationVersion  100,
    attestationSecurityLevel  SecurityLevel,
    keyMintVersion  INTEGER,
    keyMintSecurityLevel  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,
    mgfDigest  [203] EXPLICIT SET OF INTEGER OPTIONAL,
    rollbackResistance  [303] EXPLICIT NULL OPTIONAL,
    earlyBootOnly  [305] EXPLICIT NULL OPTIONAL,
    activeDateTime  [400] EXPLICIT INTEGER OPTIONAL,
    originationExpireDateTime  [401] EXPLICIT INTEGER OPTIONAL,
    usageExpireDateTime  [402] EXPLICIT INTEGER OPTIONAL,
    usageCountLimit  [405] 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,
    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,
    deviceUniqueAttestation  [720] EXPLICIT NULL OPTIONAL,
}

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

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

버전 4

KeyDescription ::= SEQUENCE {
    attestationVersion  4,
    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,
    earlyBootOnly  [305] 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,
    deviceUniqueAttestation  [720] EXPLICIT NULL OPTIONAL,
}

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

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

버전 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
키 증명 기능의 버전입니다.
버전
1Keymaster 버전 2.0
2Keymaster 버전 3.0
3Keymaster 버전 4.0
4Keymaster 버전 4.1
100KeyMint 버전 1.0
200KeyMint 버전 2.0
attestationSecurityLevel

증명의 보안 수준입니다.

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

keymasterVersion/keyMintVersion
Keymaster 또는 KeyMint 하드웨어 추상화 계층(HAL)의 버전입니다.
버전
0Keymaster 버전 0.2 또는 0.3
1Keymaster 버전 1.0
2Keymaster 버전 2.0
3Keymaster 버전 3.0
4Keymaster 버전 4.0
41Keymaster 버전 4.1
100KeyMint 버전 1.0
200KeyMint 버전 2.0
keymasterSecurityLevel/keyMintSecurityLevel
Keymaster/KeyMint 구현의 보안 수준입니다.
attestationChallenge
키 생성 시 제공된 챌린지가 포함되어 있습니다. 이 값이 Tag::ATTESTATION_CHALLENGE 승인 태그에 저장된 대로 서버에서 제공한 값과 일치하는지 확인합니다. 그렇지 않으면 서비스가 이전 증명 인증서의 재생에 취약해질 수 있습니다.
uniqueId
이 값은 제한된 기간에만 기기를 식별합니다. 이 값은 계산되며 시스템 앱에서만 사용합니다. 다른 앱에서는 uniqueId가 비어 있습니다.
softwareEnforced
선택사항. 기기의 신뢰할 수 있는 실행 환경(TEE)이 아니라 Android 시스템에서 시행하는 Keymaster/KeyMint 승인 목록입니다.
teeEnforced
선택사항. 기기의 TEE에서 시행하는 Keymaster/KeyMint 승인 목록입니다.

SecurityLevel

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

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

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

AuthorizationList

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

각 필드 이름은 유사한 이름의 Keymaster 또는 KeyMint 승인 태그에 대응됩니다. 예를 들어, 승인 목록의 keySize 필드는 Tag::KEY_SIZE 승인 태그에 대응됩니다.

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

purpose
Tag::PURPOSE 승인 태그에 대응하며, 이 태그는 태그 ID 값으로 1을 사용합니다.
algorithm

Tag::ALGORITHM 승인 태그에 대응하며, 이 태그는 태그 ID 값으로 2를 사용합니다.

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

keySize
Tag::KEY_SIZE 승인 태그에 대응하며, 이 태그는 태그 ID 값으로 3을 사용합니다.
digest
Tag::DIGEST 승인 태그에 대응하며, 이 태그는 태그 ID 값으로 5를 사용합니다.
padding
Tag::PADDING 승인 태그에 대응하며, 이 태그는 태그 ID 값으로 6을 사용합니다.
ecCurve

Tag::EC_CURVE 승인 태그에 대응하며, 이 태그는 태그 ID 값으로 10을 사용합니다.

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

rsaPublicExponent
Tag::RSA_PUBLIC_EXPONENT 승인 태그에 대응하며, 이 태그는 태그 ID 값으로 200을 사용합니다.
mgfDigest

키 증명 버전 100 이상에만 있습니다.

Tag::RSA_OAEP_MGF_DIGEST KeyMint 승인 태그에 대응하며, 이 태그는 태그 ID 값으로 203을 사용합니다.
rollbackResistance

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

Tag::ROLLBACK_RESISTANT 승인 태그에 대응하며, 이 태그는 태그 ID 값으로 303을 사용합니다.

earlyBootOnly

키 증명 버전 4 이상에만 있습니다.

Tag::EARLY_BOOT_ONLY 승인 태그에 대응하며, 이 태그는 태그 ID 값으로 305를 사용합니다.

activeDateTime
Tag::ACTIVE_DATETIME 승인 태그에 대응하며, 이 태그는 태그 ID 값으로 400을 사용합니다.
originationExpireDateTime
Tag::ORIGINATION_EXPIRE_DATETIME Keymaster 승인 태그에 대응하며, 이 태그는 태그 ID 값으로 401을 사용합니다.
usageExpireDateTime
Tag::USAGE_EXPIRE_DATETIME 승인 태그에 대응하며, 이 태그는 태그 ID 값으로 402를 사용합니다.
usageCountLimit
Tag::USAGE_COUNT_LIMIT 승인 태그에 대응하며, 이 태그는 태그 ID 값으로 405를 사용합니다.
noAuthRequired

Tag::NO_AUTH_REQUIRED 승인 태그에 대응하며, 이 태그는 태그 ID 값으로 503을 사용합니다.

userAuthType
Tag::USER_AUTH_TYPE 승인 태그에 대응하며, 이 태그는 태그 ID 값으로 504를 사용합니다.
authTimeout
Tag::AUTH_TIMEOUT 승인 태그에 대응하며, 이 태그는 태그 ID 값으로 505를 사용합니다.
allowWhileOnBody

Tag::ALLOW_WHILE_ON_BODY 승인 태그에 대응하며, 이 태그는 태그 ID 값으로 506을 사용합니다.

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

trustedUserPresenceRequired

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

Tag::TRUSTED_USER_PRESENCE_REQUIRED 승인 태그에 대응하며, 이 태그는 태그 ID 값으로 507을 사용합니다.

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

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

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

Tag::TRUSTED_CONFIRMATION_REQUIRED 승인 태그에 대응하며, 이 태그는 태그 ID 값으로 508을 사용합니다.

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

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

unlockedDeviceRequired

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

Tag::UNLOCKED_DEVICE_REQUIRED 승인 태그에 대응하며, 이 태그는 태그 ID 값으로 509를 사용합니다.

allApplications

Tag::ALL_APPLICATIONS 승인 태그에 대응하며, 이 태그는 태그 ID 값으로 600을 사용합니다.

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

applicationId
Tag::APPLICATION_ID 승인 태그에 대응하며, 이 태그는 태그 ID 값으로 601을 사용합니다.
creationDateTime
Tag::CREATION_DATETIME 승인 태그에 대응하며, 이 태그는 태그 ID 값으로 701을 사용합니다.
origin

Tag::ORIGIN 승인 태그에 대응하며, 이 태그는 태그 ID 값으로 702를 사용합니다.

rollbackResistant

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

Tag::ROLLBACK_RESISTANT 승인 태그에 대응하며, 이 태그는 태그 ID 값으로 703을 사용합니다.

rootOfTrust

Tag::ROOT_OF_TRUST 승인 태그에 대응하며, 이 태그는 태그 ID 값으로 704를 사용합니다.

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

osVersion

Tag::OS_VERSION 승인 태그에 대응하며, 이 태그는 태그 ID 값으로 705를 사용합니다.

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

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

osPatchLevel

Tag::PATCHLEVEL 승인 태그에 대응하며, 이 태그는 태그 ID 값으로 706을 사용합니다.

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

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

attestationApplicationId

키 증명 버전 2 이상에만 있습니다.

Tag::ATTESTATION_APPLICATION_ID Keymaster 승인 태그에 대응하며, 이 태그는 태그 ID 값으로 709를 사용합니다.

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

attestationIdBrand

키 증명 버전 2 이상에만 있습니다.

Tag::ATTESTATION_ID_BRAND Keymaster 태그에 대응하며, 이 태그는 태그 ID 값으로 710을 사용합니다.

attestationIdDevice

키 증명 버전 2 이상에만 있습니다.

Tag::ATTESTATION_ID_DEVICE Keymaster 태그에 대응하며, 이 태그는 태그 ID 값으로 711을 사용합니다.

attestationIdProduct

키 증명 버전 2 이상에만 있습니다.

Tag::ATTESTATION_ID_PRODUCT Keymaster 태그에 대응하며, 이 태그는 태그 ID 값으로 712를 사용합니다.

attestationIdSerial

키 증명 버전 2 이상에만 있습니다.

Tag::ATTESTATION_ID_SERIAL Keymaster 태그에 대응하며, 이 태그는 태그 ID 값으로 713을 사용합니다.

attestationIdImei

키 증명 버전 2 이상에만 있습니다.

Tag::ATTESTATION_ID_IMEI 승인 태그에 대응하며, 이 태그는 태그 ID 값으로 714를 사용합니다.

attestationIdMeid

키 증명 버전 2 이상에만 있습니다.

Tag::ATTESTATION_ID_MEID 승인 태그에 대응하며, 이 태그는 태그 ID 값으로 715를 사용합니다.

attestationIdManufacturer

키 증명 버전 2 이상에만 있습니다.

Tag::ATTESTATION_ID_MANUFACTURER 승인 태그에 대응하며, 이 태그는 태그 ID 값으로 716을 사용합니다.

attestationIdModel

키 증명 버전 2 이상에만 있습니다.

Tag::ATTESTATION_ID_MODEL 승인 태그에 대응하며, 이 태그는 태그 ID 값으로 717을 사용합니다.

vendorPatchLevel

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

Tag::VENDOR_PATCHLEVEL 승인 태그에 대응하며, 이 태그는 태그 ID 값으로 718을 사용합니다.

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

bootPatchLevel

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

Tag::BOOT_PATCHLEVEL 승인 태그에 대응하며, 이 태그는 태그 ID 값으로 719를 사용합니다.

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

deviceUniqueAttestation

키 증명 버전 4 이상에만 있습니다.

Tag::DEVICE_UNIQUE_ATTESTATION 승인 태그에 대응하며, 이 태그는 태그 ID 값으로 720을 사용합니다.

RootOfTrust

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

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

verifiedBootKey

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

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

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

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

이 값을 계산하는 방법에 관한 자세한 내용은 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

앱 서명 인증서의 SHA-256 다이제스트 집합입니다. 앱에는 여러 개의 서명 키 인증서 체인이 있을 수 있습니다. 이러한 각 체인에 대해 '리프' 인증서가 다이제스트되어 signature_digests 필드에 배치됩니다. 필드 이름은 getPackageInfo() 호출에서 반환된 Signature 클래스에 대해 명명된 것이므로, 오해의 소지가 있습니다. 다이제스트된 데이터가 앱 서명이 아닌 앱의 서명 인증서이기 때문입니다. 다음 코드 스니펫에서는 예 집합을 보여줍니다.

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

프로비저닝 정보 확장 데이터 스키마

프로비저닝 정보 확장에는 OID 1.3.6.1.4.1.11129.2.1.30이 있습니다. 확장은 프로비저닝 서버가 기기에 관해 알고 있는 정보를 제공합니다. 이 확장은 CDDL 스키마를 따릅니다.

  {
        1 : int,   ; certificates issued
  }

지도에는 버전이 지정되지 않으며 새로운 선택적 필드가 추가될 수 있습니다.

certs_issued

지난 30일 동안 기기에 발급된 인증서의 대략적인 개수입니다. 이 값이 평균보다 훨씬 큰 경우 이 값을 잠재적 악용을 나타내는 신호로 받아들 수 있습니다.