Keyboard shortcuts

Scrolling

dorCtrl+d
Scroll down
uorCtrl+u
Scroll up
Ctrl+e
One line down
Ctrl+y
One line up
gtheng
Top of article
G
Bottom of article

Articles

j
Older article
k
Newer article
O
Open original
H
Open hackernews
R
Open reddit

Lists

jor↓
Next item
kor↑
Previous item
gtheng
First item
G
Last item
oorEnter
Open selected item

Go to

gthenforgtheni
Feed
gthen1–9
Open feed entry
gthenb
Browse
gthenp
Preferences

Search and help

⌘+kCtrl+kor/
Global search
?
Show this help
Esc
Close this help

Dutch 'idealist' bank ASN blocks non-Google Android, including GrapheneOS

Worth reading the linked GitHub issue to the end: yesterday someone asked EPI (the Wero operator) directly, and the reply says hardware key attestation "proves a key was generated in a TEE or StrongBox but not app or OS integrity", which is why they want Play Integrity. That claim is wrong, and the gap matters for this whole thread.

I'm on the other side of this as a developer: a small Android app where I need some assurance that a capture came from an unmodified device, so I run both Play Integrity and the Keystore key attestation API.

What the attestation certificate actually carries, per the Android spec: the challenge you supplied, the security level (software / TEE / StrongBox), a RootOfTrust extension with verifiedBootState, the verifiedBootKey hash and deviceLocked, and an attestationApplicationId with the package name and signing certificate digest of the app that created the key. That is OS integrity (verified boot, locked bootloader) and app identity, signed by the chip, chained to Google's published roots. GrapheneOS publishes its verified boot key hashes as a signed JSON and documents how to accept them. So "a list of signing keys to be trusted" is not hypothetical, it is the documented path, and EPI's stated reason doesn't hold.

Play Integrity, by contrast, is one SDK call plus one server call to Google, and you get back an array like ["MEETS_DEVICE_INTEGRITY"]. Whether GrapheneOS is in or out is decided on Google's side; nothing in the token tells you why. In my data (64 verdicts from beta testers' phones) I have never once seen MEETS_STRONG_INTEGRITY, so in practice everyone is checking the weaker level anyway.

The honest cost of the attestation path: you parse X.509 and the ASN.1 extension yourself and you own the allowlist. My first validator unwrapped the challenge wrong and flagged 13 of my 19 stored keys as mismatched, and choked on DER lengths for 2 more. Once fixed, every real phone chained to one of Google's two roots (7 TEE, 4 StrongBox), and the only software-attested keys came from Google's own Play reviewer, who tests apps in an emulator. Today my server trusts the chain for what the key is, doesn't read RootOfTrust yet, and still gates publishing on the Play verdict, so my app would block GrapheneOS too. Not for security: because the easy check was done first, and "Google said so" is easier to defend in front of an auditor than "I maintain a list of key hashes".