So here's the concept. Rather than storing 2 keys and using a random IV, which presents its own problems (key rotation, ensuring no key is used in more than 2^32 cycles, sharing the keys, etc), is it OK to derive the cipher key, authentication key and IV from a master key? It wouldn't stop the need for key rotation policy (changing the key every 30 days), but it would greatly simplify it. So here's the concept:
MasterKey = 256 - 512 bits of CS random entropy
Then, on encrypt:
Salt = 256 bits of random entropy Derivation = PBKDF2(SHA-512, MasterKey, Salt, 10000, 640bit) CipherKey = Derivation[0:256bit] AuthKey = Derivation[256bit:512bit] IV = Derivation[512bit:640bit]
Then, the Salt is all that's shared in the ciphertext package:
Salt || CipherText || AuthText...
The few points here:
- That MasterKey should be high entropy (at least the number of bits of Cryptographically Secure random as the longest required key).
- The salt should be as strong as practical as well (CS as well), since salt collisions will automatically become cipherkey, authkey and IV collisions.
The maximum length of a single derived key should be less than the blocksize of the PRF used in PBKDF2 (to reduce exposure of the master key if a derived key is found).
For example, if you used MD5 (bs of 128 bit) to generate a 256 bit key, if that 256 bit key was found (brute force, or other weakness), the entire 128 bit output of a PBKDF2 round would be found. Therefore, the entire PBKDF2 output would not need to be brute forced, but only a single round of it (still hard, but much easier). But if the BS is larger (sha512 vs 256bit key), then finding a derived key would only give you 1/2 the output of a round, making the search much harder (since there are a LOT of inputs that would generate the same 1/2 output)...
The iteration count feed into PBKDF2 should be high enough to provide a proof of work on the derivation, but is obviously application dependent.
Based on my understanding, it demonstrates good forward security (not perfect, but good) in that if you are able to find the CipherKey or AuthKey of a particular message, they would not be applicable to future or past messages. You would need to use that information to brute force the derivation, which would be non-trivial in the least. So therefore, as long as the master key is not compromised, the individual derived keys should be safe and practically independent of each other.
Am I on track here? Or is there something that I'm missing?