duo-labs / webauthn.io

The source code for webauthn.io, a demonstration of WebAuthn.
https://webauthn.io
BSD 3-Clause "New" or "Revised" License
651 stars 120 forks source link

webauthn.io on Android: passkeys and device-bound security keys #99

Closed monperrus closed 1 year ago

monperrus commented 1 year ago

Hi!

webauthn.io is great. I notice that it does not work with some device-bound security keys on Android (the ones in the secure element of the phone, unlocked with fingerprint).

I thought first that it was a bug in the browser code, but 1) it works on Firefox and 2) it works on https://demo.yubico.com/playground

MasterKale commented 1 year ago

Hello @monperrus, webauthn.io defaults to "preferred"-ing the creation of discoverable credentials to induce Android to register passkeys via the new passkeys-centric authenticator behavior. You can change this option under Advanced Settings to "discouraged" and it should cause Android to fall back to the old authenticator behavior:

https://webauthn.io/?regUserVerification=preferred&attestation=none&attachment=all&algES256=true&algRS256=true&discoverableCredential=discouraged&authUserVerification=preferred

Can you retest with this link (it'll load the page with that option set to "discouraged") and let me know what the results are?

monperrus commented 1 year ago

hi @MasterKale I confirm that if I set "discoverable credentials" to "discouraged", then I can register with the device-bound security key ("use this device with screen lock"). Otherwise it's a confusing error message 'An unknown error occurred while talking to the credential manager.'

MasterKale commented 1 year ago

Interesting, what version of Android are you testing with? A Google Play Manager update was supposed to add passkeys support all the way back to Android 9+; the error behavior you're describing when discoverable credentials are preferred or required sounds to me like the behavior of Android prior to it getting passkeys support. 🤔

monperrus commented 1 year ago

I run a recent Android 13.

MasterKale commented 1 year ago

At this point I believe it's an issue with the phone, not the website. You mentioned earlier that you could use your phone just fine with https://demo.yubico.com/playground. I dug into this myself and noticed that Yubico's site is discouraging the creation of discoverable credentials:

Screenshot 2023-07-11 at 11 07 45 PM

The fact that this site worked for you, and webauthn.io started working for your phone once you discouraged discoverable credential creation here, can be explained by a phone that, for some reason beyond the scope of this repo, is unable to use the passkey support that Google released earlier this year.

At this point I'm inclined to close this issue since there's nothing I can do from this end. The only other thing I can think to offer you is a Google developer docs link explaining their addition of passkeys support to Android. Maybe it'll help you figure out why your phone isn't able to use passkeys:

https://developers.google.com/identity/passkeys/supported-environments

monperrus commented 1 year ago

thanks for looking into that.

Since it works well in Firefox (and not in Chrome and Brace), the phone support for passkeys works somehow.

The problem might be in the browser code, in the interaction between the browser and the phone API.

monperrus commented 1 year ago

making progress:

  1. I was able to register a passkey by switching to another Google account on the same phone -> this shows that this is neither a browser bug nor an OS bug
  2. I was able to register a passkey with the original account after the following actions:
    • click "don't use screen lock" in Settings page of Passwords
    • when registering a passkey, this prompts for "use screen lock for encryption", say yes and then it works

this is a workaround, I'd love an explanation on how passkeys and screen locks interact.

monperrus commented 1 year ago

Read more on the topic, the bug was caused by the recent "on-device encryption" feature of Google, which encrypts both passwords and passkeys: https://support.google.com/accounts/answer/11350823?sjid=12265717825297517626-EU

Basically, my Google account on the phone was in an incorrect state after activating it. The workaround described above reset the state correctly.