I'm using python.cryptography's Fernet with PBKDF2 passphrase hashing to encrypt a piece of data (the value) that is stored, encrypted, in a database. The hashed passphrase is not stored in the database, and for that reason neither is the salt. Instead, the salt comes from a password vault in the application's runtime environment, and then modified to make it unique per value.
One question I have about this is: if an attacker has the passphrase and encrypted data for one value, is it possible for them to reverse-engineer the salt (which would help them to brute force the remaining data)? What if they also have a copy of the unencrypted version of the data for that one value?
(The attack vector being considered here is one where the attacker has a regular user account on the system, and has obtained a copy of the database with the encrypted values. Thus they're able to create a single value (theirs) where they know the passphrase and the resulting encrypted value. They also have access to a copy of the application's code, since it's open source.)
Per request, here's how the salt is handled:
- The salt is generated by an adminstrator (we recommend a 32-byte random value).
- The salt gets stored in the password vault (network service)
- When the application is deployed, the salt gets injected at runtime
- When new values are saved, the secret salt is combined with a unique value ID to form the per-value salt
- This salt is then used with the user-supplied passphrase to generate a key using PBKDF2 (with 500K iterations).
- The user's values are then each encrypted with their individual keys
I believe the above is known as the "salt & pepper" pattern.