keybase / client

Keybase Go Library, Client, Service, OS X, iOS, Android, Electron
BSD 3-Clause "New" or "Revised" License
8.82k stars 1.22k forks source link

Support adding security key as new kind of "device" #17047

Open tiziano88 opened 5 years ago

tiziano88 commented 5 years ago

I would like to be able to add a Security Key (e.g. Yubikey or similar U2F key) as a "device" in keybase. The key could be enrolled via the desktop app or the mobile app or perhaps even the Keybase website (possibly using the Webauthn standard).

heronhaye commented 5 years ago

Is your suggestion that a security key could act like a paper key, so you could use it to provision other devices?

With WebAuthn, your security key generates a signing key to prove to the relying party (Keybase) that you are you. But even if Keybase believes that you are you due to your signing key, we can't let you provision another device because we don't have any of your device private keys to sign another device into your sigchain.

The WebAuthn spec does have a feature where encrypted data (say, a paper key) can be stored on Keybase servers via the credential ID, encrypted for your security key's key. But you would still need some way to extract that data from the authentication process, which isn't (as far as I know) really possible - the point of that encrypted data is to store a signing private key, not arbitrary data.

It may be easiest to store a static password which is a paper key you've generated, if your security key supports it. You could theoretically have another one of your devices be the relying party, but then you could just use that device to do whatever operation you needed to do anyway.

Let me know if I've missed some other scheme that could make this work.

tiziano88 commented 5 years ago

Yes my suggestion is to have the option to add a security key as an alternative to a paper key in the Keybase app, in that it can be provisioned from an existing device, and can be used to provision other devices.

You are actually right in that WebAuthn actually would not help here, because doing the enrollment in the browser would exclude any other device that the user owns.

I guess the way to go would be to add native support for security key in the desktop or mobile app (or both), since then it may be used to enroll a security key from an already provisioned device, and also to provision new devices by plugging in the security key when setting up the app.

Does this make sense, at least in principle?

heronhaye commented 5 years ago

Since the desktop app is using Electron it theoretically should be possible to use Chromium's support for WebAuthn. But I'm not sure how the protocol would actually work in practice without trusting the Keybase servers. Could you clarify your proposal?

tiziano88 commented 5 years ago

I am assuming essentially the current model, but in which the private key used for the signing operation when provisioning a new device is the one stored on the security key. Based on the KEX Protocol , the protocol would run almost identically: assuming the app is already provisioned on the device with a local key (either from the OS keychain or stored as a file), it then acts as both X and Y at the same time:

heronhaye commented 5 years ago

Thanks for explaining, now I understand. Is there a standard way to ask the security key to sign some data? I wonder if it's possible use webauthn with the client pretending to be a relying party and including the payload in client_data_hash.

tiziano88 commented 5 years ago

Yes I suppose the standard way in WebAuthn would be to pass the data to sign (or their hash) as the challenge (see https://developer.mozilla.org/en-US/docs/Web/API/Web_Authentication_API#Authentication). Given in our case the client is an Electron app, I imagine it may fully control the relying party string that it exposes to the key, and may decide to either set it to keybase.io (which would allow using the same security key also from a regular browser on the keybase website itself without having to enroll it separately), or to a special string that does not correspond to any actual origin.