1

I have an encoding application written in C# where users can optionally encrypt messages. I had been using the class in this answer, and it turns out I'm in good company because I found several places online that use the exact same code (one of which is Netflix's Open Source Platform).

However, comments to that answer (as well as later edits to that answer) led me to believe that this method was insecure. I opted to use the class in this answer to the same question instead.

How secure is AES encryption if you use a constant salt? How easily can this method be broken? I admit that I have very little experience in this area.

Community
  • 1
  • 1
PC Luddite
  • 5,883
  • 6
  • 23
  • 39

2 Answers2

2

AES is a block cipher. A block cipher's input is a key and a block of plaintext. A block cipher is usually used in a block cipher mode of operation. All secure modes of operation use an Initialization Vector or IV. Otherwise identical plaintext would encrypt to identical ciphertext (for the same key), and this is leaking information.

Salt is not used by AES or modes of operation. It's usually used as input for Key Derivation Functions (KDFs), especially Password Based Key Derivation Functions (PBKDFs). Dot NET's Rfc2898DeriveBytes implements the PBKDF2 function as defined in - you'd guess it - RFC 2898: "PKCS #5: Password-Based Cryptography Specification Version 2.0".

If you use a static salt in a PBKDF2 then you would get the same key as output (for the same number of iterations). Now if you would ever leak the resulting key then all your ciphertext would be vulnerable. And if you would use multiple passwords then an attacker would be able to build a rainbow table; the PBKDF2 work factor would become less important; the attacker can simply build one table and then try all the resulting keys on all possible ciphertexts.

So, as the salt is not actually used for AES it doesn't make much of a difference for the security. It is however still a horrible sin, even worse than using the default iteration count for PBKDF2 / Rfc2898DeriveBytes.


Note that horrible security sins are committed by a large number of people on a daily basis. That there are many many many persons that get it wrong doesn't tell you that you are in "good company". That there are 289 upvotes just tells you that SO answers about cryptography should not be trusted based on vote count.

Maarten Bodewes
  • 90,524
  • 13
  • 150
  • 263
  • *"Note that horrible security sins are committed by a large number of people on a daily basis. [...] That there are 289 upvotes just tells you that SO answers about cryptography should not be trusted based on vote count."* - YES. Gotta go spring up some sock-puppets to flatten the impact of such crappy legacy answers. Btw, the other downvote is mine. :) – Artjom B. Feb 01 '16 at 20:46
  • By "good company", I simply meant that there are dozens of projects searchable by Google that use the exact same code without modification (with identical salt). That and the fact that it has over 280 upvotes I find surprising having learned its apparent security flaws. – PC Luddite Feb 01 '16 at 21:08
  • It's true that leaking the key is the end of security, but so is leaking salt+secret. I don't see a reason to assume one would be more or less likely than the other. Therefore, I don't see how this static salt causes any worse security. – usr Feb 01 '16 at 22:39
  • @usr If you use a randomly generated password with 128 bits security there won't be any issues with a static salt (if you use a non-static IV). However, passwords don't usually carry that much entropy. If you just can pre-calculate the keys using a dictionary attacks than a static salt is horrible, as you only have to verify the keys, not perform the work factor. This is *especially* true if everybody copies the code *including* the static salt. – Maarten Bodewes Feb 01 '16 at 23:58
  • Does precalculation apply to encryption? I guess you would need to assume a fixed message for that or precalculate over all possible messages. – usr Feb 02 '16 at 00:03
  • @usr Tricky to explain in comments. Say you have 20 ciphertexts enciphered by 20 different keys, derived from 20 different passwords. Now as attacker you create a rainbow table (password -> key) using e.g. a dictionary and of course the static salt. Now you can just compare the generated keys against the first few blocks of each ciphertext. If you prefix the salt for each ciphertext then you need to perform the derivation for each ciphertext separately. And the derivation is the hard part because of the work factor. – Maarten Bodewes Feb 02 '16 at 00:09
  • @usr If still not convinced, read [section 4.1](https://tools.ietf.org/html/rfc2898#section-4.1) of the standard. – Maarten Bodewes Feb 02 '16 at 00:18
0

Salt is there for a reason. This enables same input to be encrypted differently. If an attacker would really insist, he can find some patterns that repeat themselves in encryption without salt, and eventually can get to your key more easily. Still the attcker would have to work very hard. Using constant salt equals to not using salt at all. And it is highly recommended to use it, as it has no effect on the decryption process.

Amir Sasson
  • 10,985
  • 1
  • 13
  • 25
  • 1
    No, the IV enables the same input to be encrypted differently. The key is always protected by the block cipher - no ciphertext will tell you anything about the key (except possibly validation of the key after you've guessed it). – Maarten Bodewes Feb 01 '16 at 20:11