-
Notifications
You must be signed in to change notification settings - Fork 383
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
MSC1703: encrypting recovery keys for online megolm backups #1703
Conversation
hm, this would be much easier to review if it were wordwrapped |
So, it feels there are three actual options here: 1a. Generate the recovery key from the passphrase (vuln to dictionary attacks on the server) What are we actually proposing in practice? I'm a bit confused as to what option 3 buys us over option 1b? |
rather than referring to option 2
splits option 2 up into two sub-options
My suggestion here is to go with 1a (now just 1 in my renumbering). The summary is that I don't think there's any realistic way of mitigating the dictionary attack: option 2b. runs through a proposed mitigation and why it doesn't really work. The kicker is that the user will get a new recovery key whenever they change their passphrase. Options 3 adds the ability to retain the same recovery key when you change your passphrase, so if we want that feature, option 1 won't suffice. It sounds like we don't though. |
### Option 2b | ||
|
||
A variant on option 2a is to regenerate K<sup>-1</sup> when the passphrase is | ||
changed, meaning the recovery does change when the passphrase is changed, |
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.
s/recovery/recovery key/
### Option 3 | ||
|
||
The backup encryption private key, K<sup>-1</sup>, and a private, | ||
passphrase-derived key, K<sup>-1</sup><sub>p</sub> are generated as above.The |
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.
s/./. /
|
||
## Security considerations | ||
|
||
The proposal above is vulnerable to a malicious server admin performing a |
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.
surely only option 1 is vuln to dict attack?
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 2b?
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 possibly 3; I haven't grokked how it works yet)
this is much clearer now; thanks. let's just say "for now let's just generate the key from the passphrase and go with option 1" as a conclusion on the MSC and give it a go. |
Yup, option 1 seems to be sufficient, and is simpler. |
Option 1 does indeed look easiest, even with the potential risk documented later in the proposal. It's also the option that was proofed in riot-web, correct? |
yup |
[It's now the only MSC for encrypting recovery keys for online megolm backups] |
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 haz comments...
@@ -0,0 +1,154 @@ | |||
# Proposal for storing an encrypted recovery key on the server to aid recovery of megolm key backups |
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.
could the file be renamed so that it matches the MSC number?
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.
please?
```json | ||
{ | ||
"private_key": { | ||
salt: "MmMsAlty", |
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.
salt: "MmMsAlty", | |
"salt": "MmMsAlty", |
{ | ||
"private_key": { | ||
salt: "MmMsAlty", | ||
rounds: 100000 |
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.
rounds: 100000 | |
"rounds": 100000 |
string, b is as follows: | ||
* Prepend the two bytes 0x8B, 0x01 to the byte string b | ||
* Compute a parity bit by XORing all bytes of the resulting string (ie. prefix | ||
+ `byte string`) |
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.
this explodes into a bullet list in the rendered version.
also why is byte string
in backticks? perhaps you just mean b
, but then you probably want to use backticks each time b is used.
In all options below, the process for generating a recovery key from a byte | ||
string, b is as follows: | ||
* Prepend the two bytes 0x8B, 0x01 to the byte string b | ||
* Compute a parity bit by XORing all bytes of the resulting string (ie. prefix |
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.
* Compute a parity bit by XORing all bytes of the resulting string (ie. prefix | |
* Compute a parity byte by XORing all bytes of the resulting string (ie. prefix |
### Option 3 | ||
|
||
The backup encryption private key, K<sup>-1</sup>, and a private, | ||
passphrase-derived key, K<sup>-1</sup><sub>p</sub> are generated as above.The |
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.
passphrase-derived key, K<sup>-1</sup><sub>p</sub> are generated as above.The | |
passphrase-derived key, K<sup>-1</sup><sub>p</sub> are generated as above. The |
|
||
The backup encryption private key, K<sup>-1</sup>, and a private, | ||
passphrase-derived key, K<sup>-1</sup><sub>p</sub> are generated as above.The | ||
passphrase key counterpart, K<sup>-1</sup><sub>p</sub>', is also generated as |
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.
there are a bunch of formulae here which are imprecisely and inconsistently described. How about giving each calculation its own line?
the passphrase key counterpart, K-1p', is calculated as:
K-1p' = K-1 XOR K-1p
K<sup>-1</sup><sub>r</sub>' is generated by XORing K<sup>-1</sup><sub>r</sub> | ||
with K<sup>-1</sup>. Both K<sup>-1</sup><sub>p</sub>' and | ||
K<sup>-1</sup><sub>r</sub>' are stored in the `private_key` in the backup under | ||
keys `passphrase_counterpart` and `recovery_key_counterpart` respectively. |
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.
how are all these keys actually used for encryption?
|
||
## Security considerations | ||
|
||
The proposal above is vulnerable to a malicious server admin performing a |
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 2b?
|
||
## Security considerations | ||
|
||
The proposal above is vulnerable to a malicious server admin performing a |
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 possibly 3; I haven't grokked how it works yet)
Is there a reason why PBKDF2 is used instead of the state of the art Argon2 ? Reference: https://password-hashing.net/ |
Mainly because there are more implementations of it. In particular, it's in WebCrypto. |
OK. I think it would be nice to have an attribute specifying the key derivation algorithm though, to make it easier to switch to a different one. I cannot find quantitative results on state-of-the-art PBKDF2 cracking but I keep reading that PBKDF2 is very weak against ASICs. |
This proposal is obsoleted by #1946 |
Rendered: https://github.com/matrix-org/matrix-doc/tree/dbkr/encrypted-recovery-keys/proposals/1687-encrypted-recovery-keys.md
This is an expanded version of MSC1687