Skip to content
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

Recovery phrase / Alternate password #249

Open
radumarias opened this issue Dec 4, 2024 · 11 comments · May be fixed by #272
Open

Recovery phrase / Alternate password #249

radumarias opened this issue Dec 4, 2024 · 11 comments · May be fixed by #272
Assignees
Labels
Milestone

Comments

@radumarias
Copy link
Member

radumarias commented Dec 4, 2024

We need a way to recover the encryption key if the user loses the password. We use a recovery phrase generated when you define the password. In case the user forgets the password, he can use this to change it. Generally, a 24-word mnemonic phrase with a strong passphrase provides 256 bits of entropy, making it extremely resistant to brute-force attacks.

Generate

  • When the user defines the password, we will ask for the user's language for the recovery phrase
  • We will generate a phrase of 24 random words from a list of the above language. You can use bip39 crate to make a 24-word phrase or make a 24-word phrase like here
  • Will print it out to stdout for the user to save it, informing him that it is very private and needs to be kept secret. Or if the user uses --out-file, we will save it there

Impl

  • For now, we encrypt the master encrypting key with a key derived from the password
  • To be able to recover based on the recovery phrase, we need to encrypt the key with a key derived from the phrase, too

Use

  • We need a new CLI arg like --recovery-phrase with the value of the phrase
  • Use this to decrypt the encryption key
  • Ask the user for a new password with confirmation
  • Re-encrypt the master encryption key with a key derived from this new password

Regenerate

  • The phrase can be used multiple times, but we need a way to regenerate it
  • Have a new arg to passwd sub-command like --refresh-recovery-phrase asking for both the password and old recovery phrase
  • It will follow the above process in Generate
@radumarias radumarias added good first issue Good for newcomers security labels Dec 4, 2024
@radumarias radumarias added this to rencfs Dec 4, 2024
@radumarias radumarias added this to the 1.0.0-rc1 milestone Dec 4, 2024
@radumarias radumarias moved this to Todo in rencfs Dec 4, 2024
@radumarias radumarias changed the title Recovery phrase Recovery phrase / Alternate password Dec 10, 2024
@Hrushi20
Copy link

Hey! I'm interested to work on this issue. I'm looking into it.

@radumarias
Copy link
Member Author

@Hrushi20 great, thank you. You can start with https://github.com/radumarias/rencfs/blob/main/CONTRIBUTING.md
Let me know any questions you might have

@Hrushi20
Copy link

Hrushi20 commented Dec 13, 2024

Hey! Had few queries.

  • How many words do we want to have for a user as part of recovery phrase?
  • I think we should use the encrypted password, add a checksum and transform it into no.of words.
  • Do we want to create a fixed length encrypted password?
  • Do we read to words into memory from file or do we store them as static variables as part of binary?

@radumarias
Copy link
Member Author

How many words do we want to have for a user as part of recovery phrase?

  • 24

Do we sha256 the user password which gives us 256 bits and add checksum of 8 bits. Do we use crc checksum or any other checksum algorithm? Adding 8 bits make it 264 bits which gives us 24 words.

  • when we do KDF from password to get the key-encryption key (KEK) we're using Argon2, which does it by hashing
  • we then encrypt the master encryption key with this key. We're using only AEAD which has a tag for data integrity and auth, so we don't need CRC as this acts like it

Do we read to words into memory from file or do we store them as static variables as part of binary?

  • if you're using bip39 crate I think it has this covered by including them in binary at build. If we implement our then use include_str. But preferably go with crates.

@radumarias
Copy link
Member Author

Played a bit with Copilor Workspaces and generated this PR https://github.com/radumarias/rencfs/pull/260 Of course is far from complete, but see if it helps as an inspiration.

@Hrushi20
Copy link

Hrushi20 commented Dec 17, 2024

Hey! I went through the code and have few doubts. On a high level, can you explain master encryption key? Are we encrypting the files with master encryption key? If the files were encrypted using key generated from old password, how would a new password help decrypting the old encrypted files?

I know the question is diverting from the issue but I want to understand the internals a bit better.

@radumarias
Copy link
Member Author

When you change or forget the password, you will decrypt the master key (DEK = Data Encryption Key) with a key derived from the old pass or recovery phrase (KEK = Key Encryption Key). You then derive a new KEK and re-encrypt the DEK with that KEK.

@Hrushi20
Copy link

Hrushi20 commented Dec 20, 2024

Hey Aes256Gcm and CHACHA20_POLY1305 contain 32 bits and hence bip39 gives us 24 words.
Algorithms generating key greater than 32 bits would result Recovery phrase greater than 24.

If algorithms generating key less 32bits, do we want to pad the key to make it 32bits to match the 24 words requirement?

Sidenote:
I'm trying to create a Proxy to ensure end users are not directly dependent on bip32 crate.

@Hrushi20 Hrushi20 linked a pull request Dec 21, 2024 that will close this issue
1 task
@Hrushi20
Copy link

@radumarias, bip39 library needs a 128-256bits input to generate recovery_phrase.

@radumarias
Copy link
Member Author

input as entropy? or for what?
if so, you can use our function for that in crypto module

@Hrushi20
Copy link

Hrushi20 commented Dec 26, 2024

So I am using the password directly to create the recovery_phrase. Users don't use such huge passwords.

Flow, User enter password which is converted to Recovery Phrase
Password -> Recovery Phrase

When user Tries to use Recovery Phrase to create new Password
Recovery Phrase -> Old Password
Old Password + Salt -> Old Derived Key
Old Derived Key (decrypt) -> Decrypted Master Key
New Password + Salt(existing) -> New Derived Key
New Derived Key + Decrypted Master Key -> Encrypted Master Key

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants