キー構成証明を使用してハードウェア格納型キーペアを検証する

キー構成証明を活用すると、デバイスのハードウェア格納型キーストア内に、アプリで使用するキーが格納されるため、信頼性が向上します。以下のセクションでは、ハードウェア格納型キーのプロパティを検証する方法と、構成証明書の拡張データを解釈する方法について説明します。

注: 実稼働レベルの環境でデバイスのハードウェア格納型キーのプロパティを検証する前に、デバイスがハードウェア レベルのキー構成証明をサポートしているか確認する必要があります。そのためには、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 Hardware Attestation Root 証明書で署名された構成証明キーを使用しています。なお、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 は、そのハードウェアのセキュリティについて何も主張しません。これは、キーが不正使用されているということではなく、キーがセキュアなハードウェア内にあることを証明書が証明できないだけです。必要に応じて、セキュリティの前提条件を調整します。

ルート証明書にこのページの公開鍵が含まれていない場合は、次の 2 つの原因が考えられます。

  • ほとんどの場合、デバイスには 7.0 より前の Android バージョンが搭載されていて、ハードウェア構成証明がサポートされていません。この場合 Android は、同じタイプの構成証明書を生成する構成証明書をソフトウェア レベルで実装していますが、この構成証明書は Android ソースコード内にハードコーディングされたキーで署名されています。この署名キーは秘密ではないため、構成証明書は、セキュアなハードウェアであることを装った攻撃者によって作成されたものの可能性があります。
  • 他の原因としては、デバイスが Google Play デバイスではないことが考えられます。その場合デバイス メーカーは、独自のルートを自由に作成し、構成証明書の意味する内容についても自由に主張できます。デバイス メーカーのマニュアルをご覧ください。なお、この記事の執筆時点において、このような設定を行っているデバイス メーカーは、Google が知る範囲では存在しません。

証明書失効ステータス リスト

構成証明キーは、誤操作や攻撃者による抽出の疑いなど、さまざまな理由で失効することがあります。したがって、構成証明書チェーン内の各証明書のステータスを、公式の証明書失効ステータス リスト(CRL)と照合する必要があります。このリストは Google によって管理され、https://android.googleapis.com/attestation/status で公開されています。HTTP レスポンスの Cache-Control ヘッダーによって更新を確認する頻度が決まるため、検証するすべての証明書に対してネットワーク リクエストを行う必要はありません。この URL から、通常の有効なステータスを持たない証明書の失効ステータスが記載された JSON ファイルが得られます。JSON ファイルの形式は、次の JSON スキーマ(Draft 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 Hardware Abstraction Layer(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

このデータ構造は、キーペアなどのソフトウェア機能が、デバイス内に存在している場所に基づいて保護される範囲を示します。

データ構造は列挙型であるため、次のいずれかの値を取ります。

Software
ソフトウェア機能を作成、管理するロジックは、Android システム内に実装されています。キーペアを作成して保存する目的の場合、この場所は TEE よりも安全性が低くなりますが、アプリのプロセス領域よりも安全です。
TrustedEnvironment
ソフトウェア機能を作成、管理するロジックは、TEE などのセキュアなハードウェアに実装されています。キーペアを作成して保存する目的の場合、セキュアなハードウェアはリモートからのセキュリティ侵害に対して堅牢なため、この場所は比較的安全です。
StrongBox
ソフトウェア機能を作成、管理するロジックは、専用のハードウェア セキュリティ モジュール内に実装されています。キーペアを作成して保存する目的の場合、リモートからのセキュリティ侵害やモジュールへのハードウェア攻撃に対して堅牢なため、この場所は、さらに安全です。

AuthorizationList

このデータ構造には、Keymaster または KeyMint Hardware Abstraction Layer(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 システムのキーストア内で楕円曲線(EC)キーペアを生成する際に使用されるパラメータ セットで、ECDSA を使用して署名と検証を行います。

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 Protected の確認をご覧ください。

注: このタグが適用されるのは、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
デバイスのブートローダーがロックされている場合、この値は true になります。これで、確認付きブートチェックが有効になり、署名されていないデバイス イメージがデバイスにフラッシュされることを防止します。この機能の詳細については、ブートを確認するをご覧ください。
verifiedBootState
確認付きブート機能に応じたデバイスのブート状態
verifiedBootHash

キー構成証明バージョン 3 の場合に限り存在します。

確認付きブートによって保護されるすべてのデータのダイジェスト。確認付きブートの Android 確認付きブート実装を使用するデバイスの場合、この値は、VBMeta 構造体(確認付きブート メタデータ構造)のダイジェストを含みます。

この値の計算方法については、VBMeta ダイジェストをご覧ください。

VerifiedBootState

このデータ構造は、デバイスの現在のブート状態を示します。これは、デバイスのブートが完了した後にユーザーやアプリに提供される保護のレベルを示します。この機能の詳細については、「ブートを確認する」のブートの状態セクションをご覧ください。

このデータ構造は列挙型であるため、次のいずれかの値を取ります。

Verified

ブートローダーや、ブート パーティション、すべての検証済みパーティションなどを含む信頼チェーン全体を示します。

デバイスがこのブート状態のときは、デバイスに組み込まれた証明書のハッシュが verifiedBootKey になります。この証明書は、デバイス メーカーが出荷前にデバイスの ROM に追加します。

SelfSigned

デバイスに組み込まれた証明書によってデバイスのブート パーティションが検証されていて、署名が有効であることを示します。

デバイスがこのブート状態のときは、ユーザーによりインストールされた証明書のハッシュが verifiedBootKey になります。この証明書により、メーカーが提供する元のブート パーティションの代わりに、ユーザーがデバイスに追加したブート パーティションが署名されます。

Unverified
ユーザーがデバイスに自由に変更を加えられることを示します。そのため、デバイスの整合性を検証する責任はユーザーにあります。
Failed
デバイスの検証が不合格だったことを示します。構成証明書が、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 日間にデバイスに対して発行された証明書のおおよその数。この値が平均よりも数桁大きい場合、不正使用の可能性があります。