0
$\begingroup$

I have a private text note to store on my remote server. I'd like to encrypt my data in my web browser, using JavaScript, before uploading it. Here is what I currently do:

  1. Edit my note in a textarea.
  2. Click the Encrypt and upload button.
  3. The JS asks for a new password.
  4. This password is then prepared using PBKDF2.
  5. Then the resulting key is used with AES-GCM to encrypt the note.
  6. Uploading the encrypted data (and the initialization vector from step 5).

Question is:

Is it safe to use a hardcoded salt in step 4?

What would be the benefits of generating a random salt each time I click the Encrypt and upload button? (Then prepending the salt to the encrypted data and the initialization vector.)

How could an attacker benefit from a hardcoded salt in this case?

$\endgroup$
3
  • $\begingroup$ I don't even understand the reason of using a salt at all in my case, because the password based derived key is not stored anywhere, just used for the AES-GCM encryption with a random initialization vector. $\endgroup$ Commented Nov 17 at 17:04
  • 1
    $\begingroup$ Doesn't matter that you're not storing the password hash explicitly. The ciphertext acts as a password hash equivalent. An attacker would throw password guesses through the hashing function and then check if the resulting key can decrypt the ciphertext and mac properly. It is the same process as when trying to crack a regular password hash. $\endgroup$
    – n-l-i
    Commented Nov 19 at 13:52
  • $\begingroup$ The whole point of a salt is that it's a unique value. You don't want different people or passwords deriving the same key. You also want password guessing to be as difficult as possible. Then there are limits on the amount of data you can encrypt with a single key. Rotating the key helps prevent nonce reuse. $\endgroup$ Commented Nov 19 at 19:16

3 Answers 3

1
$\begingroup$

No, it's not safe to use a fixed salt. Salts are random. The reason for using a random salt is that if two people used the same password and run it through your implementation they'll create different keys. If you use a hard coded salt then the same password would result in the same key being computed.

$\endgroup$
3
  • $\begingroup$ Thank you, but is my case the same as storing password hashes of several users in a database? Without random salt, same passwords result in the same key, I see. But what's wrong with that, in my case? The key is not stored, not transmitted. Its only purpose is to use it for the encryption. Then, the key is deleted immediately. Only the ciphertext is uploaded and saved. (And the initialization vector. Which is unique for each encryption, so the AES results will differ from each other, even if the PBKDF2 keys are always the same.) $\endgroup$ Commented Nov 18 at 0:37
  • 1
    $\begingroup$ Two users with the same password could then decrypt one another's ciphertexts. Not storing the key doesn't matter, it's still wildly insecure. $\endgroup$ Commented Nov 18 at 1:13
  • $\begingroup$ I'm the only user. $\endgroup$ Commented Nov 18 at 1:43
1
$\begingroup$

One of the problems of not using a random - or at least unique - salt is that you will always be using the same key. That means that an adversary can (pre-)compute lots of keys from a set of passwords and try to decrypt or verify the authentication tag using these pre-computed keys. Fortunately an adversary won't be able to use rainbow tables (presuming that the ciphertext is still randomized using a nonce - see the next session), but it is at least possible for them to use e.g. a single AES block decrypt to check if the computed key is likely valid. They may also test it against several ciphertexts in case different passwords are used.

If the nonce is also not unique then GCM fails catastrophically, both with regards to authentication of the messages as with the confidentiality of the generated messages. As your browser's JS is generally not able to use a counter or other deterministically calculated unique value that means that the nonce would have to be randomized. At that point it makes more sense to simply use a random salt and create separate keys for different messages.

Quite often both the key and nonce are derived from the same salt & password, but in principle a key derived from a random salt and password is unique enough to use a static / all zero nonce.

$\endgroup$
6
  • $\begingroup$ I don't quite understand your first point about using the same key. The nonce exists so that keys can be reusable without a compromise in security. So I would assume the weakness in the scheme is the password. The password is the same for each key generation, so what would be the benefit of using a different key for each encryption here be? I assume an attacker would just pick one ciphertext and its auth-tag and then check password guesses against that. Is there a more efficient attack if one has access to more ciphertexts encrypted with the same key? $\endgroup$
    – n-l-i
    Commented Nov 19 at 19:58
  • $\begingroup$ No, but that doesn't avoid the (pre-)computation attacks as explained in the first section, and if you have access to random values, then why would you use a static / known salt? If you don't have any issues with storing a nonce or salt then why not simply follow best practices? $\endgroup$
    – Maarten Bodewes
    Commented Nov 19 at 20:44
  • $\begingroup$ I think the biggest point is that a single key cannot be used indefinitely, particularly with a small random nonce like AES-GCM. A salt is also meant to be a unique value, so the salt parameter is being misused. This is some sort of optimisation to avoid storing extra data, but it's better to rotate the key. Just look at things like AES-GCM-SIV and DNDK-GCM. $\endgroup$ Commented Nov 20 at 8:38
  • $\begingroup$ What is this "best practice" you're referring to? And what are "(pre-) computation attacks" and how would using random salts prevent them? The salt is stored next to the ciphertext regardless so I can't see much benefit of random salts compared to a static salt per user. $\endgroup$
    – n-l-i
    Commented Nov 20 at 9:30
  • $\begingroup$ @MaartenBodewes Oh wait are you referring to the drawbacks of having the salt be public vs it not being public? I guess that would enable a precomputation attack, being able to start deriving keys from potential passwords before the salts have been leaked $\endgroup$
    – n-l-i
    Commented Nov 20 at 9:36
-1
$\begingroup$

Each different password should always have its own unique salt. But there is no reason for the same password to be hashed with different salts for each key generation, unless you actually want different keys. But the attack vector against your password and encrypted notes would not change based on whether the salt stays the same for your password or not.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.