AppAttest attestKey returns invalid key error

Dear Experts,

I have App Attest deployed in an app that is currently in TestFlight. Its works OK most of the time.

For one particular user, however, attestKey fails with DCErrorInvalidKey for a new key that it has just created.

I have some insight into what the app is doing because I send diagnostics to the server. It seems that for this user, the sequence of events is:

  1. Initially the app has no key ID saved.
  2. The user initiates an action that requires App Attest-signed communication with my server.
  3. The app calls generateKey which seems to succeed.
  4. The app fetches a challenge from the server.
  5. The app calls attestKey.
  6. attestKey returns DCErrorInvalidKey.
  7. The app doesn't save the key ID persistently, so next time the same thing happens.

attestKey really shouldn't fail with the invalid key error for a key that it has just created, should it?

What could be going on here?

Does anyone know what the expected behaviour is on a hacked device? Presumably App Attest is expected to fail; does it fail by returning DCErrorInvalidKey from attestKey?

FB13679917

I've now found that these users also fail DeviceCheck's device validation.

Are you ensuring that you are calling attestKey after generateKey has succeeded? Both of these methods are async, so you should not be attempting to synchronously call one after the other.

As to the DCErrorInvalidKey, that indicates:

  • keyId is nil
  • keyId is invalid (i.e., from a previous App installation)

Oh wow, a reply!

I'm actually in the process of removing AppAttest from these apps because it has proved too unreliable, and I got no useful responses to my bug report or posts here. I've already removed it from one app and I've literally been doing that for the second today. Even a quite small rate of false-positives from App Attest is enough to get 1-star reviews from users and consequently a crash in sales.

Anyway, to answer your questions:

Are you ensuring that you are calling attestKey after generateKey has succeeded? Both of these methods are async, so you should not be attempting to synchronously call one after the other.

Yes. I was even extracting the key ID (see the FB).

As to the DCErrorInvalidKey, that indicates: keyId is nil keyId is invalid (i.e., from a previous App installation)

That does not explain what I was seeing. I asked above, could it indicate a cracked device? If not, how is a cracked device expected to behave? I.e. at what point would I get an error?

Anyway, thanks for your interest in my problems, even if it has come too late to be of any use.

P.S. my FB number, with more details, is above. That includes links to some other forum posts reporting related problems.

We're seeing the same in our app. Situation:

We perform attestation on first app launch (and in the rollout to existing users) like this (all asynchronously):

  • generateKey
  • (get a challenge from our server)
  • attestKey
  • send result to server
  • if server responds successfully, we store the keyID for later use in assertion.

We also noticed that for some users attestKey generates the DCErrorInvalidKey error in some cases (~0.1% of our users, but as OP mentioned, each false positive blocked user is one too many). Our logs indicate that the keyID is not reused multiple times, and it's also not nil. Also, from what we can see this error is persistent for the users that encounter it: if we detect this specific error we allow users to retry generating a new key, to no avail.

It makes me wonder whether the DCErrorInvalidKey error is also returned in undocumented cases, besides the provided key being nil or being already used before for attestation, and how to deal with those.

Any insight on this would be very helpful.

AppAttest attestKey returns invalid key error
 
 
Q