converse.js
converse.js copied to clipboard
Persistent Pseudorandom OMEMO Keygen
As seen in #3134, there is some desire for persistent OMEMO key generation. Users often clear browser information, including session storage, cookies, etc, on a regular basis, often to preserve their privacy. However, when those users use converse with OMEMO, they essentially sacrifice authentication by deleting their OMEMO keys on every browser shutdown. Other users are trained to implicitly trust any keys these users publish, because they always enter with a new key, which completely defeats the entire purpose of authentication.
We could solve this by allowing users to export/import OMEMO keys as files. But this introduces two new problems in and of itself:
- Users don't like extra steps. In including a button to import/export, users will very rarely use this feature unless they are very 'cryptographically' educated, no matter how many advice blurbs or warnings we display to them. It's just not something people like to do unless they already care about it. Realistically speaking, I think I know maybe one or two people who would make use of this feature.
- In practice, I assume a large number of users will engage in the practice of cloud backups of their keyfiles. Some devices, like apple devices and chromebooks, assume cloud storage of files as essentially the default. And even worse, they are stored in the cloud in plaintext. So users will completely expose their plaintexts on a regular basis if not properly educated. If these files are encrypted, they will be encrypted with a password, and all cryptographers hate passwords.
But... if the best case scenario for a large portion of our users here is to use passwords to secure their keys... Maybe we should just embrace this and skip the middle man? Thankfully, the use of password managers has become normalized. Users are using strong, random passwords to log into websites now, especially the "problem users" who regularly clear their browsing history for privacy reasons. And thanks to the widespread introduction of SCRAM, we can reasonably envision a setup where the authenticating XMPP server never actually sees the users password, only the hash of the ClientKey and the key derivation parameters are necessary to store on the server, even during password submission (though I don't think this is presently supported in most XMPP servers, it wouldn't be a terribly difficult thing to add, with confirmation from a cryptographer that it doesn't break anything :) ).
So what if we used the user's login password as the input to a password based key derivation function to generate semi-persistent OMEMO keys? We would obviously be making a big sacrifice to the security of the long term identity key - passwords are pretty easy to break, but we'd be making a huge step forward in regards to authentication. And if users actually do use strong, random passwords, like those that are generated by password managers, then we get the best of both worlds.
In short, I really don't think there is a great solution here that covers all the bases. The correct solution would be for users to be educated in cryptography and keep their keys hidden and persistent, or to stop using web browsers, both of which are unlikely.
I would like to work with a cryptographer to develop a protocol for deriving reasonably sound keys using this method, and to review the following outline:
- User generates a strong, random
password
, and a randomsalt
, and a reasonable iteration countiter
for their device. - Client generates the SCRAM
ClientKey
as usual, and sends the serverH(ClientKey)
,iter
, andsalt
for storage. - Client computes
keymaterial = argon2id(password, Username || 'static-omemo-key-v1')
whereargon2id(pw, slt)
is instantiated with globally reasonable parameters (to be determined). - Client uses the
keymaterial
to derive an OMEMO identity key, and a (signed) prekey.
I would really appreciate it if someone else could take a look at it and provide some critique. Thank you. In the meantime, here is a rough checklist of what would have to be done:
- [ ] OMEMO key import/export, for advanced users
- [ ] Sufficient warning about how generating key material from a password could compromise security, allow users the choice to disable this
- [ ] Add features to ejabberd and prosody to submit SCRAM information without revealing the
SaltedPassword
- [ ] Generate key info as described in the scheme
And, optionally,
- [ ] Maybe break if the password entropy is (naively) calculated to be too low? This should at least stop rockyou passwords from making it through as key material.