Closed mcm-ham closed 3 months ago
This is actually a tricky one. I remember hesitating to do it, then forgot.
The main concern is that if you use another lib server side, it expects bytes as challenge. Now, if you encode/decode from string to bytes, the next question is what character encoding to use. So it should state in the fine print that it uses UTF-8 to encode the string into bytes, that is then base64 encoded again in the json payload. Confusing right? In the end, I opted it to be base64 encoded from the start.
I'll improve the docs
My previous message was kind of confusing. For the sake of clarity...
The underlying protocol expects "bytes" as challenges, and until now base64url is used everywhere for conversion between text and bytes. That's also what most other server-side libraries expect.
Now what would happen if I change the logic to "let's encode any text to bytes using UTF-8 instead"? Well, nothing much actually except two things. First, a slightly heterogenous handling of binary values. Secondly, more subtle, that servers need to adapt their logic slightly. For non-js ecosystem, they usually generate random bytes as challenge, send it as base64url, and verify these bytes in the registration/authentication payload. The server-side would have to adapt the logic into producing a text (which is rarely produced by a secure random), then use the UTF-8 encoded version of this text as bytes to verify against. That's fair enough, but it still increases the cognitive overhead.
That makes sense, thanks for the explanation.
The other thing noted is https://webauthn.passwordless.id/authentication/#3-send-the-payload-to-the-server does not match the new value returned that aligns with JSON version of PublicKeyCredential.
I'll leave the challenge as base64url. However I leave this ticket open until I improved the docs. I'll also add a server.createChallenge()
to make things easier/safer.
There was already utils.randomChallenge()
. I moved it to server.randomChallenge()
and documented it.
Just trying out this library but got an error from util.parseBase64url with atob saying input is invalid. I see client.register is calling this function, after base64 encoding the challenge i.e. btoa it now works. Is it a requirement that challenge is base64 encoded if so should this be mentioned in the docs or did I miss that somewhere?