- From: Emil Lundberg via GitHub <sysbot+gh@w3.org>
- Date: Tue, 15 Oct 2019 13:58:00 +0000
- To: public-webauthn@w3.org
>`S` must be kept secret, otherwise collaborating RPs can forge an otherwise valid credential id and test whether a user holds the corresponding private key, which uniquely identifies the user. This is a weak guessing attack violating unlinkability. Aha, _there's_ the attack enabled by knowing `S`! We've known that anyone who knows `S` can create a valid credential ID that the backup authenticator would accept and use, but we hadn't found a way to leverage that into an attack. Thanks! Might it make sense, then, to include an EDH key agreement in the import/export exchange, and encrypt `S` with the agreed ephemeral key? It wouldn't prevent a malicious client from active-MitMing the exchange and learning `S` (since we can't reasonably authenticate DH public keys across different authenticator vendors), but at least there would be forward secrecy and `S` wouldn't be in cleartext in client memory if the client is benign. >Currently, Bob / the backup device is required to verify an alleged `E` is not invalid according to SEC 1, section 2.3.4. This procedure still allows for the `E` to be the point at infinity, which is invariant under scalar multiplication. This allows for a powerful attack on unlinkability: > >[...] The RP can then subtract `cred_key * G` from P to learn `S` which uniquely identifies the user. > >Consequently, devices must ensure `E` is not the point at infinity (or any low order point in a non-prime order group). Good catch, we'll add that. This also has me thinking it might make sense to include the `rpIdHash` in the HKDF `info` parameter (in which case we could probably drop `rpIdHash` from the MAC)? >Why use each half of `HKDF(e * S)` as opposed to two distinct invocations of HKDF with different labels? Wouldn't the latter be cleaner? Yeah, that might be cleaner. It also shouldn't make a difference in terms of performance cost as you'd need to run one HKDF-Extract and two HMAC-Hash in either case. >Why add `cred_key * G` to `S`? What purpose does it serve over using `cred_key * G` directly? If you don't, then `p = credKey` and the main authenticator therefore knows the backup credential private key. With `P = cred_key * G + S`, you need to know `s` to compute `p = cred_key + s`, so only the backup authenticator is able to exercise its backup credentials. @dainnilsson @ve7jtb thoughts on this? -- GitHub Notification of comment by emlun Please view or discuss this issue at https://github.com/w3c/webauthn/issues/931#issuecomment-542225765 using your GitHub account
Received on Tuesday, 15 October 2019 13:58:02 UTC