6

I'd like to incorporate the encryption and decryption of files in one of my C# .NET apps. The scenario is simple: User A sends an AES256-encrypted file to user B. The clear text password is exchanged on a different channel (e.g. phone call or whatever).

From what I understand I should use Rfc2898DeriveBytes for converting the user's clear text password into a more secure password using maybe 10,000 rounds. (see this article).

What I don't understand is the role of salt in my scenario. Usually salt is used in hashing passwords to prevent dictionary attacks. But in my scenario the PBKDF2 algo is used to compensate weaknesses of short or easy to guess clear text passwords by adding extra calculations required by the PBKDF2-rounds.

If I choose a random salt then the receiver will need to know that salt also in order to decrypt correctly. If I use a constant salt, then hackers can easily reverse engineer my code and run brute force attacks using my constant salt (although they'll be really slow thanks to the PBKDF2 iterations).

From what I understand I have no choice but to use a constant salt in my scenario and enforce a good clear text password rule to make up for the weakness of constant salt. Is my assumption correct?

Community
  • 1
  • 1
Marco
  • 700
  • 5
  • 11

2 Answers2

6

Salts, in the context of password hashing (and key derivation), are used to prevent precomputation attacks like rainbow tables.

Note that the salt must be different and unpredictable (preferably random) for every password. Also note that salts need not be secret – that's what the password is for. You gain no security by keeping the salt secret.

The recommended approach in your case is to generate a random salt every time a file is encrypted, and transmit the salt along with the ciphertext.

Is there a specific reason you're using AES-256 by the way? It's around 40% slower than AES-128 due to the extra rounds, and it offers no practical security benefit (particularly not in the case of password-based encryption).

It's also worth considering using a well-established standard like PGP rather than building your own protocol from cryptographic primitives, because building secure protocols is so hard that even experts don't always get it right.

ntoskrnl
  • 5,714
  • 2
  • 27
  • 31
  • There should be random IV for AES (I assume he is using some mode other than ECB which is not secure). Salt is preventing using rainbow table to get password from a hash, but attacker have no method of obtaining this hash in this scenario because it is only used as a key for encryption. – Maciej S Dec 11 '13 at 22:04
  • 2
    @MaciejS An attacker could precompute a huge number of keys from common passwords and use the table against any number of messages without doing further work. – ntoskrnl Dec 11 '13 at 22:08
  • You are right salt should be used to prevent this kind of attack. – Maciej S Dec 11 '13 at 22:13
  • What do you mean by "building my own protocol"? What is wrong if I use RijndaelManaged from the .NET framework to encrypt a file using a securely generated password? Shouldn't it be secure by design since I'm using libraries developed by expers? Or am I missing your point? – Marco Dec 11 '13 at 22:29
  • ok I think I get it now: So you're suggesting to use salt even in my approach because it will add another layer of security against precomputed password tables. Even though the salt will be visible to everyone, its randomness will prevent huge password tables from appearing on the net somewhere. This sounds very reasonable to me. – Marco Dec 11 '13 at 22:43
  • Take also a look [here](http://crypto.stackexchange.com/questions/5440/can-i-use-my-random-iv-for-aes-as-a-salt-for-pbkdf2) – Maciej S Dec 11 '13 at 22:46
  • He meant that it is better to use well established standard than doing your own. In crypto it is really easy to do something that will not be secure without realizing this. For example if you choose wrong mode of operation and do not use authentication someone could tamper your file without you realizing this. – Maciej S Dec 11 '13 at 22:53
  • 2
    A properly used salt prevents multi-target attacks, not just pre-computation. A salt being unpredictable isn't that important either. – CodesInChaos Dec 11 '13 at 23:07
  • 1
    @user3092904 "What is wrong if I use `RijndaelManaged` from the .NET framework " Just because one building block is written by an expert doesn't mean the system you build on top is secure. For example you might use the IV improperly, forget the MAC, use the MAC improperly,... Using low level crypto APIs is tricky and most developers get it wrong. – CodesInChaos Dec 11 '13 at 23:10
  • @user3092904 Technically, you can't encrypt a file with AES, because it's just a mapping function between 128-bit pieces of data. You need to build a protocol around it to encrypt a file. For instance, the simplest protocol defines a mode of operation and a padding. As CodesInChaos is said, building a secure protocol out of such low level primitives is very difficult. Somebody witty once said that programming crypto is like arming a bomb. – ntoskrnl Dec 12 '13 at 10:15
  • 1
    +1 although the sentence "You gain no security by keeping the salt secret." is not correct. The salt could be constructed out of a publicly known salt and a static salt value in the code, for instance. In that case you need to know both the salt value in the database and the one in the code. If those are accessible by different roles this trick can be used to provide another layer of security. – Maarten Bodewes Dec 15 '13 at 23:56
  • OK I've been wrapping my head around the answers and I'm still not convinced. Here's why: Please IGNORE AES encryption for the moment. I'm only talking about the importance of IV for *KEY DERIVATION*: Assume user A derives a secred key using PW "house" and a random IV. Now we also need to transmit the random IV to the recipient so that he can derive the exact same key. An attacker can just intercept the IV and feed his own Rfc2898DeriveBytes instance with it for a brute force attack. So where exactly is the added security benefit over a constant, hard-coded IV in this case? – Marco Jun 02 '14 at 14:14
  • @Marco Again, it has to do with precomputation. In your example, the attacker could precompute a large number of keys using a word list. The key would always be the same for a certain password. However, that's not the case if a random IV is used in the derivation algorithm. – ntoskrnl Jun 02 '14 at 15:37
  • @ntoskrnl: Thanks a lot, I understand now. So the IV is really an added security feature to prevent attacks with pre-calculated dictionaries. This of course assumes that the attacker knows the number of derivation rounds and the static IV. Both of them are not particularly hard to find out, I admit. On the other hand, my system's clear text passwords are so hard to brute force (e.g.: dG.L2#h%:L_U) that using a static IV wouldn't be an real security issue. If, however, users were using passwords like "house", then I absolutely see your point. Thanks again. – Marco Jun 02 '14 at 19:07
0

Your assumption is correct. If they have access to the password, they will also have access to the salt. The BCrypt implementations I've seen put the number of iterations, the hash, and the salt all in the same result string!

The idea is: your hash should be secure even if the salt and number if iterations is known. (If we could always know that the salt and number of iterations and even the algorithm would be unknown to attackers, security would get a whole heck of a lot easier! Until attackers politely decline to read our salts, we must assume they will have access to them in the event of a breach.) So you're right, they can brute force it - if they have a few supercomputers and a couple million years of computing time at their disposal.

corsiKa
  • 81,495
  • 25
  • 153
  • 204