-
Notifications
You must be signed in to change notification settings - Fork 385
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Initial MSC for encrypting recovery keys for online megolm backups #1686
Conversation
|
||
[MSC1219](https://github.com/matrix-org/matrix-doc/issues/1219) proposes an API for optionally storing encrypted megolm keys on your homeserver, so if a user loses all their devices, they can still recover their history. The megolm keys are public-key encrypted using a private Curve25519 key that only the end-user has. | ||
|
||
However, there are usability concerns about users having to store their Curve25519 recovery private key in a secure manner. Casual users are likely to be scared away by having to file away a relatively long (e.g. 10 word) generated recovery key. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I presume, if you are taking inspiration from FileVault, the system should also ask you to file away the generated key anyway? IIRC FileVault both encrypts your key with your UNIX password and has you write down the seed for the unencrypted key somewhere, just in case you forget your password.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yup. I will clarify, but the idea is that backing up your megolm keys, and backing up the recovery key is optional too. You can always keep a copy of the recovery key too offline.
We propose storing it using the /account_data API: | ||
|
||
```json | ||
PUT /_matrix/client/r0/user/{userId}/account_data/m.recovery_key |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The recovery key will be different for different backup versions, so maybe we should have a different name for each version. Also, we should probably put it in the m.megolm_backup
namespace, for consistency with the backup spec. Maybe something like m.megolm_backup.v1.<backupversion>
?
|
||
{ | ||
"algorithm": "m.recovery_key.v1.curve25519.pbkdf2", | ||
"data": <base64>, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
will also need to store a salt. Could also store other PBKDF2 parameters, such as number of rounds, so that people can be more paranoid if they want to.
* the `m.hidden` event field to indicate to the server that such events should not be included in /sync responses to clients. | ||
* a `GET /_matrix/client/r0/user/{userId}/account_data/m.recovery_key` accessor, symmetrical to the existing PUT method, to access the data when needed. | ||
|
||
We deliberately encrypt the Curve25519 private key rather than deriving it from the passphrase so that if the user chooses not to store their encrypted recovery key on the server, they can benefit from a Curve25519 key generated from a high entropy source of random rather than being needlessly derived from a passphrase of some kind. (TODO: Is this accurate)? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think this is accurate, as users who want high entropy can just use a randomly generated base64 string or something similar as their passphrase. I think the main benefit of encrypting the private key is that you change the passphrase without re-encrypting everything.
|
||
In practice, this means: | ||
* Mandating that clients use a high complexity passphrase to encrypt the recovery key - either by enforcing complexity requirements or by generating it for them (similar to 1Password's password creation UX). | ||
* Symmetrically encrypting the Curve25519 key by N rounds of PBKDF2(key, passphrase) where N=100,000 - similarly to how we encrypt [offline megolm key backups](https://github.com/matrix-org/matrix-doc/issues/1211) today. (TODO: This needs to be fleshed out). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
...and then presumably we need to hit the private key with AES to actually encrypt it with the key/iv from the PBKDF2?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@uhoreg if you can suggest how we should actually do this bit of it, it'd be much appreciated
Closing in favour of #1703 (which is what I'm told is supposed to happen) |
Rendered: https://github.com/matrix-org/matrix-doc/tree/matthew/encrypted-recovery-keys/proposals/1687-encrypted-recovery-keys.md