spacedrive
spacedrive copied to clipboard
[ENG-283] Key manager refinements
This PR refines the key manager pretty heavily, and I'm a lot more comfortable calling it stable now. The UI for these changes isn't perfect.
Main changes:
- Key manager is locked until a valid password+secret key combo are provided. This is currently "password" and
MDAwMDAwMDAwMDAwMDAwMA==(16 zeroes encoded in base64). This will be changed once we have proper onboarding. - Nothing plaintext is stored in memory. The master password is now hashed on entry, and that is stored in memory. We have instant access to all of the keys, and only need to hash each plaintext key with the content salt now.
- We can verify the master password and secret key combination are correct (with the use of a nil-UUID "verification key")
- Key mounting time was reduced by half (due to hashing the master password on entry)
- An "Unmount all & lock" button was added, for quickly removing everything from memory.
- The "sync with library" button is functional, and if disabled the key will only be stored in memory.
- The crypto crate got
serdefeature gating - The key settings page was populated, and it now functions just the same as the key manager itself
- Passphrase generation! Current passphrases are 7-words long, using the EFF large wordlist (the index has been removed so we can easily select words), and they're separated with
-. This gives each passphrase 7776^7 possible combinations (which is an insane amount!), but we can always swap this wordlist out if needed.
Below is a preview video of these changes. This is in real-time, with no cuts (in prod):
https://user-images.githubusercontent.com/77554505/200555466-d8eb258b-a61b-4adb-bf11-af7bec99e873.mp4
This also closes ENG-305.
ENG-283 Key manager refinements
The key manager needs some additional work doing before it is production-ready.
It currently stores both the master password and any mounted keys in plaintext in memory, which isn't ideal. There's also no way to verify the master password is correct (nor any way to set said master password).
We can solve these issues by just hashing the master password once on entry, and storing it in memory instead, removing the need for the plaintext master password after this initial hash. This also means we'd be able to reduce the number of hashes required to add+mount a key, which will make the whole experience a lot nicer for the user.
My current plan to solve the lack of a master password verification is to introduce a zero-UUID key, which is kept updated with the current master password. This is always obscured from keystore dumps/retrieval. When a user enters the master password, we attempt to decrypt this key - if it's incorrect, we're able to re-prompt the user for the password. We should probably allow the user to choose the hashing parameter level of this password during onboarding, which is also where they will be provided with the master password.
I've deliberated a lot over the format of such password, but I think a 7-word diceware password using the EFF large wordlist will be the most suitable. This gives us 7776^7 total combinations of passphrases, while still making them somewhat memorable (the user is extremely likely to copy/paste a completely random password, and they may set an insecure one if allowed to).
I also plan to allow changing the master password, but we'd have to advise against selecting a weak one. I think implementing zxcvbn would be pretty helpful.
There is also the issue that a master password compromise may lead to a total compromise of all encrypted data. We're going to need to push for the user to store their master password safely, and we could always implement something such as a "secret key" used by other password managers (that was @jamie's idea). This secret key's primary use is in a server/client situation, and protects against a compromised server. Provided it's not too much of a hassle for the user, and we can push for them to write it down/store it offline, we could likely benefit from something such as this. It'd mean a master key compromise wouldn't be a total compromise of all encrypted data, as the attacker would still have to guess 256^16 bytes to hash the key correctly (which would get very expensive very fast with Argon2id). 256^16 bytes is a lot less than the full 256^32 bytes (for the master key itself), but it's still a lot.
The details of these refinements are not set in stone, and I'd need to double check that the crypto is sound - these are mostly just ideas for optimizations at the moment.
The latest updates on your projects. Learn more about Vercel for Git ↗︎
| Name | Status | Preview | Updated |
|---|---|---|---|
| spacedrive-web | ❌ Failed (Inspect) | Nov 10, 2022 at 2:36PM (UTC) |
1 Ignored Deployment
| Name | Status | Preview | Updated |
|---|---|---|---|
| spacedrive-landing | ⬜️ Ignored (Inspect) | Nov 10, 2022 at 2:36PM (UTC) |
ENG-305 Master Password Generation
Add support in the crypto library for generating a master password.
I think a 7-word diceware password using the EFF large wordlist will be the most suitable, but this can always be changed in the future.
Converting to draft until tomorrow morning, the settings page needs to be updated to follow the new "lock" system.
(fixed, courtesy of @maxichrome)