You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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. 23
(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
If at all possible, use a library, which provides a high-quality all-in-one solution
for AEAD encryption and proper key derivation.
xen-orchestra/@xen-orchestra/fs/src/_encryptor.js
Line 43 in 700149d
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
If at all possible, use a library, which provides a high-quality all-in-one solution
for AEAD encryption and proper key derivation.
Personally, I highly recommend libsodium, if it is at all possible to use it with your project.
They even have a good example of this usecase in their documentation https://doc.libsodium.org/secret-key_cryptography/secretbox and a JS Version is available at https://www.npmjs.com/package/libsodium.
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
The text was updated successfully, but these errors were encountered: