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

[Security] Missing Key Derivation for Encrypted Backups #7909

Open
moberer opened this issue Aug 11, 2024 · 0 comments
Open

[Security] Missing Key Derivation for Encrypted Backups #7909

moberer opened this issue Aug 11, 2024 · 0 comments
Assignees

Comments

@moberer
Copy link

moberer commented Aug 11, 2024

const cipher = crypto.createCipheriv(algorithm, Buffer.from(key), iv)

Overview

Currently, the user can input a password in the UI, in order to encrypt a backup.

This currently works by effectively directly putting the password string into the
key buffer.

This is not a recommended practice as it leads to a weaker protection from a variety of attacks (for details see below).

It is highly recommended to use a cryptographic KDF (key derivation function) 1. (detailed recommendations for this are below).

A KDF serves to significantly slow down brute-force attacks, increases resilience for relatively short keys, prevents key-reuse even with the same password (due to a random salt) and increases the entropy of the encryption key.

Likely Impact

The current problem will likely cause short to medium-length passwords to become breakable, while long passwords have a reduced amount of effective protection.

Problems with the current approach

Reduced Key Space

The direct usage of a user-provided password string with a limited size as a key reduces the effective key-space significantly.

See the following example:

Direct usage of an Alpha-Numeric String (approximation of a user password)
10 numbers + 2 * 26 letters = 62 possibilities / Byte
62 ^ 32 = 190 effective bits

Note that in most cases, the actual strength will be even less,
since usually user-chosen passwords are significantly shorter than
32 characters.

Fully Random Bytes (Ideal Case):
1 byte random number = 2^8 = 256 possibilities / Byte
256 ^ 32 = 256 effective bits

Reduced Resistance to Brute-Force Attacks

Pure AES is quick to execute. - This also means that decrypting the first block to check whether the decrypted data makes sense is quick. Thus, brute-force attacks can make progress quickly.

Hence, especially for bad passwords such attacks can have success. 1, history section

KDFs limit this, as they are designed to take up processing time and memory, to make parallel or hardware-assisted brute-forcing much slower.

Key-Reuse Prevention

In the current setup, users with the same password will use the same encryption key!

This has the downside that more encrypted material with the same key is available,
which in turn makes a large variety of different attacks easier.

This is especially problematic, as the re-use of a (key, nonce)-pair is disastrous for AES-GCM. 2 3
(And the nonce is randomly chosen from "only" 2^96 values).

[It should also be considered if moving away from AES-GCM would be better. (See the above and common limitations in literature)]

Recommendations

Concrete Fix

  • Use a key derivation function before using a user password as an encryption key.
    The currently recommended most recomended functions are argon2id or scrypt (in that order).

  • Remove the 32 character limit for encryption passwords.

General Advice

Credits & Thank you

Thanks @Morpheus0x for writing his decryption tool (https://github.com/Morpheus0x/gocryptor), which brought my attention to this and who helped me while finding the issue.

Edit History

  • 2024-08-11 Opened Issue
  • 2024-08-12 - 14 Clarifications and Restructuring, Added Impact Section
  • 2024-08-15 Added References
@julien-f julien-f self-assigned this Aug 12, 2024
@moberer moberer changed the title Security / Missing Key Derivation for Encrypted Backups [Security] Missing Key Derivation for Encrypted Backups Aug 13, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants