39

I wrote a simple file encryption program as an example of how to do encryption correctly, but after reading a questions about encryption + MAC, I think I made a mistake by using the same key for both.

I'm about to fix my program to generate a longer key and split it, but I'm wondering, what bad things happen when you do this?

Brendan Long
  • 2,878
  • 1
  • 19
  • 27
  • 1
    You should post a specification of your encryption scheme on your programs website so it's possible to see if you correctly combined your building blocks. I see two potential weaknesses in it (mac-then-encrypt and overlong output from PBKDF2), both more severe than the key-reuse. But I need a spec to confirm. – CodesInChaos Jun 22 '13 at 17:42
  • 1
    @CodesInChaos I'm not sure how to write that. The [source](https://bitbucket.org/brendanlong/python-encryption/src/b746eb371b695730b5c2475350daae6cc5beefce/encryption.py?at=master) is pretty simple (if you understand Python). I'll put a step-by-step of what it does in the question. – Brendan Long Jun 22 '13 at 17:46
  • 1
    Don't put it into this question, a question should be only about one thing. But having a short spec on the program's website describing the modes of encryption, the order in which you apply things, how exactly you derive keys, etc. is a good idea. – CodesInChaos Jun 22 '13 at 17:52
  • 1
    @CodesInChaos I added a "high level view section". Basically, I use PBKDF2-SHA1, AES-128-CFB, and HMAC-MD5 (I chose these because they're the defaults, and one of the points I was trying to make is that you shouldn't change them unless you know what you're doing). I encrypt the data, then generate the HMAC of the encrypted data (which I think is the right order?). – Brendan Long Jun 22 '13 at 18:09
  • 2
    I think this question is relevant to your question http://crypto.stackexchange.com/questions/8081/using-the-same-secret-key-for-encryption-and-authentication-in-a-encrypt-then-ma – Ali Ahmad Jun 22 '13 at 18:18

1 Answers1

47

Using one key for multiple purpose is considered bad style in general. It doesn't directly imply a vulnerability. I violate this principle occasionally, if it is convenient for protocol design.

The most important reason for this is that, if you use the same key for multiple schemes, you need to consider interactions between the different schemes. With independent keys you don't need to worry about this.

Another concern is that one scheme might get broken, allowing key recovery. That key recovery then breaks all parts of your protocol that used that key. For example, if you implement a bad MAC algorithm, a break against that algorithm might not only break the authentication but also the confidentiality of your message.

Some practical examples:

  • Using AES-CBC for encryption together with AES-CBC-MAC is totally broken if you use the same key.
  • Using AES for encryption together with HMAC-MD5/SHA-1/SHA-2 has no known interactions. It is implausible that there are such interactions.
  • AES-CCM is a mode that uses AES-CTR for encryption and AES-CBC-MAC as MAC. This mode is provably as strong as AES itself.

These examples show that the practical security of such a combination can range from totally broken to provably secure.


The proper approach is to start with with one master key and use a key-derivation-function, such as HKDF, to derive individual keys. These keys are independent, preventing interactions between the different schemes. It is not feasible to recover the master key from individual keys, so a break against one part of the system doesn't break everything else based on that master key.

CodesInChaos
  • 11,854
  • 2
  • 40
  • 50
  • So in my case (AES-CFB + HMAC-MD5), it's probably fine, but since this is meant as an example for beginners, I should use two keys anyway, just so I don't give people the wrong idea? – Brendan Long Jun 22 '13 at 18:14
  • 1
    @BrendanLong I'd use HKDF to create two independent keys from the natural sized output of PBKDF2 (20 bytes for PBKDF2-HMAC-SHA-1). I only violate the "use a key for a single purpose" principle only if it offers significant advantages, which is not the case in your example. – CodesInChaos Jun 22 '13 at 18:19
  • I was planning to just make PBKDF2-SHA1 generate a key of length AES_128_KEY_SIZE + MD5_DIGEST_SIZE, then split it into two keys. What's the advantage of using HKDF? – Brendan Long Jun 22 '13 at 18:44
  • 2
    @BrendanLong It's more than the natural output size of SHA-1, so the defender suffers a performance hit, the attacker does not. Check your issue tracker for details. – CodesInChaos Jun 22 '13 at 19:07
  • 1
    @CodesInChaos What about using the hash of the key as a second key? Two distinct keys are used in this case but only one key is managed. – Moustache Jun 22 '13 at 20:32
  • I just switched to PBKDF2-SHA256 for my program, since PyCrypto doesn't come with HKDF and implementing it would go against the spirit of the example – Brendan Long Jun 22 '13 at 20:36
  • 4
    @Moustache The problem with that is that you used the key for two purposes: 1) To encrypt 2) as input for the hash to derive the second key. So it's still bad style. The proper way is to derive both keys from the master key using a keyed hash. HKDF is essentially HMAC where you use the master key as key and you provide different strings as message to derive different keys. – CodesInChaos Jun 22 '13 at 20:47
  • It helps answering one of my questions [here](http://security.stackexchange.com/questions/37655/build-a-secure-channel-without-ssl-tls). Thanks – Moustache Jun 22 '13 at 20:56