19

I am using PHP's mcrypt library and the AES-256 (rijndael) algorithm, which requires both a key + initialization vector to run.

My logical brainside isn't really going along with this. Isn't just one key enough?

Theoretical scenario:
If I had encrypted sensitive data stored in a database, which only the owner should be able to decrypt, would it be appropriate to use the users hashed password to either the key or the initialization vector to his or her data?

Should the key be considered more private than the initialization vector or is it the other way around?

rook
  • 66,304
  • 38
  • 162
  • 239
Industrial
  • 41,400
  • 69
  • 194
  • 289

4 Answers4

12

No, in fact an IV is vital in most implementations. The IV is also considered to be safe for public use, for instance the IV is transmitted in plain text for WEP and WPA1/WPA2. The problem arises when this same key+iv is used to encrypt the same plain text. The cipher texts will be identical, unless you use an IV. If an attacker can encrypt arbitrary plain text with this key, and then view the cipher text. This is a much faster way of brute forcing other cipher text that the attacker has obtained.

Not only that, the IV must be random or you would be in violation of CWE-329. The reason why this is a problem is a bit more subtle and I didn't get it at first. You didn't mention this, but i hope you are using either the CBC or CMAC modes

The use of a hash function on a password is nearly identical to using a String2Key function. This is a solid design so long as an attacker can't use SQL Injection to obtain the key.

Community
  • 1
  • 1
rook
  • 66,304
  • 38
  • 162
  • 239
  • Hi Rook. That was all news to me. Thanks a lot! I should be safe then if I used `CFC` with a non-random IV? – Industrial Feb 24 '11 at 19:02
  • @Industrial Actually its `CBC` mode, and the IV **must** be random. In a database you can have a column for the iv and generate this number using `mt_rand()`. – rook Feb 24 '11 at 21:05
  • @Rook Hmm. I wasn't able to decrypt my encrypted strings without having a IV that is consistent between encryption & decryption, so no random there really. Maybe I am doing something wrong or are you saying that the IV always should be completely randomized? – Industrial Feb 24 '11 at 21:11
  • @Industrial yes the IV must be random. You do need the same key+iv for encryption and decryption. Think of it this way the IV modifies the key before it is being used. If you are using the same key+iv i suspect there is a bug in your code. – rook Feb 24 '11 at 21:15
  • @Rook - Thanks for the clarification. A theoretical question, If i would encrypt a file, I couldn't use the filename as a base for an IV as it may change and the same goes for an hash of the contents as it may change. What would be appropriate for this? Generating random IV and storing separately in a DB? – Industrial Feb 24 '11 at 21:19
  • 1
    @Industrial well that is a bit different. Ideally you'd have your own file type, which isn't that complex. For instance you could have the first X number of bits of the file as your IV. Look at what block cipher your using and find the max IV size. – rook Feb 24 '11 at 22:08
  • @Industrial, @Rook: or, have the first byte of your file be the length of the IV – davka Feb 25 '11 at 14:12
7

Initialization Vector (IV) is not a key at all, and is not secret. In fact, it is often exposed (e.g. prepended to the encrypted data). It is used as an additional random input to the encryption algorithm so that the result of encrypting the same clear data is different each time you use a different IV. This way, statistics cannot be gathered on the encrypted data. It does not "improve" the encryption strength by itself.

You can look here for nice diagrams showing how and why IV is used.

davka
  • 13,974
  • 11
  • 61
  • 86
7

Do not use hashed password as a single source for key and IV. As a rule of thumb, you should generate random IV EVERY TIME you update encrypted data and store IV with this data. Key can be reused multiple times, but use salted hashing and store salt with data too.

If you just hash user passwords and use it as encryption keys, users with same passwords will have same keys. Depending on your database structure and intruder access rights there could be some unfortunate cases when users with same passwords can be detected. Add at least unique username to this hash.

If you do not change IV for every data update, information about data changes can be leaked. With CBC or CFB mode identical first plaintext blocks will be encrypted to identical ciphertext until first plaintext change, so position of this change can be determined.

blaze
  • 4,326
  • 18
  • 23
  • So instead of one field in the DB you now need at least 3? Encrypted value, IV and Salt ? We can even add the key to it that would make it 4 fields in the DB (ofc I wouldn't save the key to DB though). Sounds like a lot of work, possibly unnecessary? – ZurabWeb Feb 27 '15 at 15:08
  • 1
    Why? Salt and IV are fixed-length, just prepend it to encrypted/hashed data and separate when needed. – blaze Feb 27 '15 at 19:01
0

If you're using the EBP mode of the block cipher, or most of the stream ciphers, identical key+IV combinations on different plaintexts will offer the attackers a direct view on the XOR result of the key. This by extension reveals the key itself and to some extent the password.

But do I mean IVs are definitely necessary? No. As long as you change your password each and every time on your next plaintext block(even the same block the second time), you're completely fine without IVs. In fact, all that an IV does is the automation of the above process.

  • What's EBP mode? Never heard of that one and a quick search doesn't turn up anything up either. OFB and CTR mode leak the keystream since they're effectively stream ciphers. But no popular mode leaks the key itself. – CodesInChaos Mar 12 '15 at 09:50