The certificate has two lists.

Research

8 min read

Type: Primer

Category: Research — Keys & Secure Hardware

Series: Key containers on mobile devices, part 2 of 3

Reading time: ~9 min

Android key attestation is the only widely available way to prove to a remote party where a key lives — provided the verifier reads the right half of it.

The previous article ended on a limitation: every local method of asking what protects a key runs inside the application's own process, and reports whatever the platform says. That is adequate for choosing what to attempt and useless as evidence.

Key attestation is the mechanism that produces evidence. It matters most for credential issuance — an issuer signing a device-bound credential such as an mdoc or an SD-JWT VC with key binding needs to know that the holder's key is where the holder's software claims it is — and it is regularly consumed incorrectly.

What the certificate is

Requesting attestation at key generation causes the keystore to return a certificate chain rather than a bare key. The leaf is a standard X.509 v3 certificate with a fixed serial number of 1 and a fixed subject of CN=Android Keystore Key — neither carries information. The content sits in an extension with OID 1.3.6.1.4.1.11129.2.1.17.

That extension contains a DER-encoded structure:

KeyDescription ::= SEQUENCE {
    attestationVersion         INTEGER,
    attestationSecurityLevel   SecurityLevel,
    keyMintVersion             INTEGER,
    keyMintSecurityLevel       SecurityLevel,
    attestationChallenge       OCTET_STRING,
    uniqueId                   OCTET_STRING,
    softwareEnforced           AuthorizationList,
    hardwareEnforced           AuthorizationList,
}

SecurityLevel takes the same three values as the previous article: Software, TrustedEnvironment, StrongBox. attestationChallenge carries a nonce supplied by the verifier, which is what makes the certificate a fresh statement rather than a replayable one.

The two lists

AuthorizationList appears twice, and the difference between the two occurrences is the whole point of the mechanism.

The hardwareEnforced list contains authorizations collected or generated by code inside the secure hardware, not controlled by the platform. The TEE or secure element vouches for them and enforces them on every use of the key.

The softwareEnforced list contains authorizations enforced by the Android platform. AOSP's own framing is that these are trusted only as long as the device is running an OS that complies with the Android Platform Security Model — bootloader locked, verified boot in the Verified state.

The same tag can appear in either list. Which list it appears in determines what a verifier may conclude:

  • purpose, algorithm, keySize, ecCurve, digest, origin, noAuthRequired, userAuthType, rollbackResistance in hardwareEnforced: the secure hardware itself constrains how the key can be used. A key marked sign-only cannot be used to decrypt; a key requiring user authentication cannot be used without it.
  • The same tags in softwareEnforced: the constraint exists only as OS policy. It holds while the OS is intact and evaporates when it is not.

Two tags are always software-enforced and this is expected rather than suspicious. attestationApplicationId — which application requested the key — and creationDateTime have no meaning inside secure hardware, which knows nothing about packages or wall-clock time. They are still useful, but they are platform statements, not hardware statements.

The verifier's obligation follows: read the security level, and separately confirm that each authorization you are relying on appears in the hardware-enforced list. A key can carry attestationSecurityLevel = TrustedEnvironment while an authorization the issuer cares about sits on the software side. Checking only the level, or checking only that a tag is present somewhere, produces a conclusion the certificate does not support.

The rest of the structure

Root of trust.

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

VerifiedBootState is Verified, SelfSigned, Unverified or Failed. For an issuer, verifiedBootState = Verified and deviceLocked = true are the conditions under which the software-enforced list means anything at all.

A parsing note: verifiedBootHash is absent in attestation schema versions 1 and 2. A parser written against the current schema will fail on older devices.

Patch levels. osVersion, osPatchLevel (as YYYYMM), vendorPatchLevel, bootPatchLevel. These let an issuer set a floor on how stale a device's software may be.

Identity fields. attestationIdBrand, Device, Product, Manufacturer, Model, Serial, Imei, Meid, and a second IMEI field from KeyMint 3. These require specific device support, are gated by the platform, and are frequently unavailable to third-party applications. Do not design an issuance flow that depends on them without confirming availability on the target device population.

Validating the chain

The verifier builds the chain from leaf to root and confirms the root is a published Google attestation root.

There are currently two. The long-standing root is RSA-signed. A new ECDSA P-384 root was introduced as part of the transition to remote key provisioning and began signing chains on 1 February 2026. A verifier must trust both, and can distinguish them by the root's signature algorithm: SHA384withECDSA for the new one, SHA256withRSA for the legacy one. Whether and when devices chain exclusively to the new root is a transition detail to confirm against Google's current documentation rather than assume.

Revocation status is published as JSON at https://android.googleapis.com/attestation/status, keyed on certificate serial number. It changes, so a verifier fetches it rather than embedding it.

Google publishes a Kotlin verification library, android/keyattestation. Using it is preferable to writing an ASN.1 parser for a structure with version-dependent fields and two lists that are easy to confuse.

A correction worth stating explicitly, because the two cases are widely conflated. Google's documentation observes that a device without hardware attestation is not thereby untrustworthy — the absence of attestation is a neutral signal, not a negative one, because plenty of legitimate devices simply lack the capability. That reasoning does not extend to a revoked certificate. A revoked certificate must fail validation of the attestation evidence it carries. The two situations are "we have no evidence" and "the evidence we have is void," and they call for different decisions.

Remote key provisioning

Historically, attestation keys were injected at the factory in batches, with a single key shared across at least 100,000 devices so that the attestation key could not serve as a device identifier. Remote key provisioning replaces this with per-device keys provisioned over the air, carrying short-lived certificates.

The practical consequences for an issuer:

  • Two chain structures coexist. A factory-keyed device presents a chain through a vendor intermediate to the legacy root, with a long-lived leaf. An RKP device presents a rotated leaf through a provisioned intermediate to the newer root.
  • Certificate validity windows are short. An issuer cannot cache a chain indefinitely and treat it as current.
  • The extension schema is identical in both cases. Only the roots and the key lifecycle differ.

The exact status of RKP across releases — supported, required to be implemented, or the only mechanism for devices launching on a given version — is stated differently in different AOSP documents and is worth reconciling against current documentation before writing it into a specification.

What attestation does not prove

Five limits, each of which has produced a wrong assumption somewhere:

It does not prove the requesting application is genuine. attestationApplicationId is software-enforced. On an intact device it identifies the caller; on a modified one it does not.

It does not prove the secure hardware is sound. Attestation is a statement made by the TEE about itself. Published work has extracted hardware-protected keys from a major vendor's TEE keymaster implementation through IV reuse, together with a downgrade attack that forced patched devices back into vulnerable behaviour. A certificate from a broken TEE is a correctly signed statement of something false.

It does not prove the chain is real on every device. Devices whose attestation keyboxes have leaked can be used to forge attestations, and tooling to do so circulates. This is a large part of why revocation checking and RKP exist.

It does not root in Google on every device. Hardware attestation is a standard AOSP capability and does not require Google Mobile Services to produce a certificate. But on a device without GMS certification, the chain roots in the manufacturer's own attestation root. A verifier that only trusts Google roots will reject an otherwise perfectly hardware-backed key. Supporting such devices means maintaining additional trust anchors, obtained through each manufacturer's own channels.

It does not prove anything about enrolment. The certificate says where a key is. It says nothing about whether the person presenting it is who the credential will claim they are.

The verifier's checklist

  1. Generate the key with a server-supplied challenge; confirm the challenge in the certificate matches.
  2. Build and validate the chain to a trusted root; support both Google roots, plus any manufacturer roots your device population requires.
  3. Check the revocation status list, freshly fetched.
  4. Check certificate validity windows.
  5. Read attestationSecurityLevel and keyMintSecurityLevel.
  6. Confirm every authorization you rely on is in the hardware-enforced list.
  7. Confirm verifiedBootState = Verified and deviceLocked = true before granting any weight to software-enforced content.
  8. Apply a patch-level floor appropriate to the credential's value.
  9. Record the whole chain and the parsed result. When a decision is questioned years later, the certificate is the only evidence that survives.

Steps 6 and 7 are the ones most often skipped, and skipping them turns a proof into a formality.

Series: Key containers on mobile devices


References

  1. Android Open Source Project. Key and ID attestation. https://source.android.com/docs/security/features/keystore/attestation
  2. Android Developers. Verify hardware-backed key pairs with key attestation. https://developer.android.com/privacy-and-security/security-key-attestation
  3. Google. android/keyattestation verification library. https://github.com/android/keyattestation
  4. Android Open Source Project. Remote key provisioning. https://source.android.com/docs/core/ota/modular-system/remote-key-provisioning
  5. Shakevsky A, Ronen E, Wool A (2022). Trust Dies in Darkness: Shedding Light on Samsung's TrustZone Keymaster Design. 31st USENIX Security Symposium, pp. 251–268. IACR ePrint 2022/208.
  6. GrapheneOS. Attestation compatibility guide. https://grapheneos.org/articles/attestation-compatibility-guide

Related Articles

Three connected trust objects: a sealed glass sphere, a metal token and a ceramic credential card.

The other three questions.

Most cryptography education for children begins and ends with confidentiality. Integrity, authentication and credentials can be modelled with simple roles and objects, even as age-assurance systems make those properties part of children’s digital lives.

Paper envelope with a glass seal, metal key and ceramic blocks on a pale surface.

Cryptography can start before algebra.

Children can learn the questions cryptography answers before they can learn the mathematics behind its algorithms. Existing school materials teach secrecy well, but leave integrity, authentication, identity and trust comparatively unexplored.

Three compact containers of translucent glass, matte ceramic and machined metal arranged on a pale laboratory surface.

What “hardware-backed” means on Android.

Android exposes software, TEE-backed and StrongBox-backed keys through one keystore API. The effective security level, mandated algorithm set and available attestation evidence vary by device and release.