Reference example of AppTest server-side implementation

Hi,

We have a multi-platform application that requires integrity attestation before the backend will enable supporting services (fairly common scenario).

I've read the documentation for DeviceCheck and AppAttest, as well as SafetyNet on the Android side.

The Android documentation includes lots of examples of use, including server-side (though oddly in C# and Javascript... which I don't see as being server-side languages, but... oh, well).

Anyway, maybe there's a server-side example of using an application attestation on the server when validating a client, as well as validating individual requests with assertions, but I've not been able to find it.

It seems like a relatively important bit of functionality to ensure that apps aren't being compromised, while at the same time requiring a correct implementation... Why not give a reference implementation as a starting point to make sure developers are on the right path?

Can anyone point me at an example as a Gist, etc?

Thanks.

Post not yet marked as solved Up vote post of PhilipTP Down vote post of PhilipTP
2.7k views
  • Found a few examples on GitHub, but what's worrying is that they don't closely follow the steps outlined in Validating Apps that Connect to Your Server.

    In particular, this part:

    Create the SHA256 hash of the public key in credCert, and verify that it matches the key identifier from your app.

    But this is far from being unambiguous. I'd have thought that this referred to the entire DER of the public key:

    % openssl x509 -in k -noout -pubkey | openssl asn1parse -inform pem -dump     0:d=0  hl=2 l=  89 cons: SEQUENCE               2:d=1  hl=2 l=  19 cons: SEQUENCE               4:d=2  hl=2 l=   7 prim: OBJECT            :id-ecPublicKey    13:d=2  hl=2 l=   8 prim: OBJECT            :prime256v1    23:d=1  hl=2 l=  66 prim: BIT STRING               0000 - 00 04 09 1a ae 9f d2 0b-89 e6 6b ab 68 3e 70 e1   ..........k.h>p.       0010 - 6d 0f b1 2f 8b 4b bd c9-d2 54 ec 15 2c b4 fc 4c   m../.K...T..,..L       0020 - 8d fb e1 49 0d 90 34 80-10 82 08 6c 49 58 7e 2c   ...I..4....lIX~,       0030 - 5b 90 2b 80 2d 1f f3 e9-36 59 51 d2 3e 1d d2 f8   [.+.-...6YQ.>...       0040 - 75 e3                                             u.

    But from what I can tell, the checksum is only on the BIT STRING itself from looking at other examples... but even then, extracting just this portion and checksumming only that, I can't match the keyId.

    Hmm... Can't seem to format block code...

Add a Comment

Replies

And the answer is, the public key needs to be serialized as an X9.62 Uncompressed Point in order for the digest to match... this is not called out anywhere.

  • I'm struggeling at the same step,can you explain how you have converted your key to get a digest match? Thanks and best regards Lenny

  • Ok, this was the most frustrating afternoon I've had in a while. I came to this answer because I wanted to implement step #5, which is verifying the hash of the public key and the keyId generated by iOS matched. A gigantic thanks for @PhilipTP for pointing me in the right direction with his comment/answer!

    @MNTC (and other confused about what the answer actually means), the public key in the first cert in the x5c array (what apple calls the Credential Certificate or credCert in their doc) will be an ECDSA public key. You need to extract the x and y params from that public key and, per https://security.stackexchange.com/a/185552 literally just concatenate them and prepend with 0x04.

    Full nodejs example for this step can be found at this gist: https://gist.github.com/apottere/043a4fd006fc4cf79692af813bdb4cd4#file-index-ts-L24-L29

  • In case anyone is having the same problem in PHP, I just solved it and published my whole verification code in this gist: https://gist.github.com/gbalduzzi/0f2f14c3511da9e7811ad6f3a0175d06

Add a Comment

I'm trying to implement this in TypeScript, and I'm stuck on the step "Decode the sequence and extract the single octet string that it contains. Verify that the string equals nonce."

This is my implementation so far. I'd be grateful for any help anyone can provide.

Hello, I've implemented a Typescript library to verify Attestations and Assertions: https://github.com/srinivas1729/appattest-checker-node