passwordless-id / webauthn

Webauthn / passkeys helper library to make your life easier. Client side, server side and demo included.
https://webauthn.passwordless.id
MIT License
454 stars 53 forks source link

Compatibility with 1Password and Bitwarden #37

Closed marknijboer closed 1 year ago

marknijboer commented 1 year ago

I have been testing with this library and it really makes authentication via WebAuthn simple to use. I've tested it through Chrome passkey storage, Apple KeyChain (FaceID) storage and it all works perfectly. Recently both 1Password and Bitwarden added support for saving and using passkeys and I am running into issues with that. I was a bit sad that I could not get it to work, because once my password manager supports it I feel confident enough to actually start using it instead of using it more like a gimmick :)

In 1Password I straight up get an error during a passkey registration breaking on an unimplemented internal function response.getPublicKey. When I test with Bitwarden it seems to work, but upon further inspection the public key is an empty string:

{ id: 'NmqWB5ibSYef0hoShh9Zyw', publicKey: '', algorithm: 'ES256' }

Weirdly enough, the serverWebAuthn.verifyRegistration on the server side succeeds with this empty public key but logging in does not, breaking on DataError: Invalid keyData, which seems logical.

Getting to the point of this issue: I know WebAuthn support is in its early phase, certainly for these password managers. I get the feeling that both managers do not support this response.getPublicKey function (yet). But these password managers have tested their setup and felt confident enough to release it to the public, which gives me the idea that there are other ways to get the public key that are possibly better supported among WebAuthn providers.

Are you aware of other ways to do this, and what are your thoughts on this?

Edit: I was actually able to login to Github with a passkey, which proves that the Bitwarden implementation is usable

dagnelies commented 1 year ago

Thanks for your interest. Indeed, 1Password / Bitwarden do not work properly because they do not implement the getPublicKey. By the way, this method is mandatory according to the specs.

That said, it is also possible to extract the public key from the raw byte buffers. However, besides digging in low-level byte structures, it also requires a CBOR decoding library. This adds both complexity and an undesired depency for this lib striving to be slim and simple.

My thoughts on it is that it would be nicer for 1Password / Bitwarden to implement this method rather than all library maintainers working around its absence.

... I should also throw an exception during registration. Noted.

marknijboer commented 1 year ago

Thank you for your response. A WebAuthn library that works in most situations is preferred, but I understand your design decision.

I did some research and beside the requirement for the CBOR library you'd most likely also need one or more libraries to get the public key into DER format. All in all, this would clutter up the WebAuthn library, only to make up for the password managers not doing their part.

Let's hope the password managers will adhere to the specification soon.

marknijboer commented 12 months ago

I just wanted to let you know that 1Password seems to be working in the browser since version 2.17.0 (released last week). Let's hope Bitwarden will soon follow :-)

holow29 commented 11 months ago

... I should also throw an exception during registration. Noted.

Just to add to this, according to the spec (§ 5.2.1.1 Easily accessing credential data), you should be checking to see if 'getPublicKey' is supported since older user-agents might not support it:

Note: getPublicKey() and getAuthenticatorData() were only added in level two of this spec. Relying Parties SHOULD use feature detection before using these functions by testing the value of 'getPublicKey' in AuthenticatorAttestationResponse.prototype. Relying Parties that require this function to exist may not interoperate with older user-agents.