-1

In order to have an encrypted file who's key can be changed without needing to encrypt the whole file again, I'd like to encrypt the file with a main key ,and then encrypt that main key with another one which the user will keep.

My question is - can I also encrypt a MAC (Message Authentication Code) key and store it in the file beside the MAC itself, or will that introduce a weakness? (The user will have another MAC key to authenticate the main (encrypted) encryption and MAC keys.)

Let's assume using AES-CBC and HMAC-SHA256

EDIT

This is the general idea:

  1. Encrypted main_AES_Key || main_MAC_Key (encrypted with user-stored_AES_Key).
  2. IV.
  3. MAC of all of the above (using user_stored_MAC_Key).
  4. Encrypted message (using main_AES_Key).
  5. IV.
  6. MAC of 4+5 (using main_MAC_Key).
e-sushi
  • 17,891
  • 12
  • 83
  • 229
ispiro
  • 2,005
  • 2
  • 18
  • 29
  • What would the purpose of storing the MAC key in the file be? You can't verify the MAC on the file without the knowing the MAC key a priori. If you don't know the MAC key a priori, then an attacker can forge a file with substitute contents to put in any MAC key they like, and compute a MAC with that key. – Squeamish Ossifrage Jul 27 '17 at 20:43
  • @SqueamishOssifrage That's why I added: The user will have another MAC key to authenticate the main (encrypted) encryption and MAC keys.. – ispiro Jul 27 '17 at 20:54
  • Can you write out approximately what the format you intend to use a little more formally, in the style of https://github.com/Tarsnap/scrypt/blob/master/FORMAT? It's hard to follow exactly what you're MACing and encrypting. – Squeamish Ossifrage Jul 27 '17 at 21:04
  • @SqueamishOssifrage See edited question. – ispiro Jul 27 '17 at 21:25
  • $\DeclareMathOperator{\AE}{AE}$So you're storing the concatenation of two messages, effectively, authenticated-encrypted with independent keys $k_u$ derived (say) from a user's password, and $k_m$ for the main message: (i) $\AE_{k_u}(k_m)$, (ii) $\AE_{k_m}(m)$, where $m$ is a large message. Here AE is AES-CBC (why not AES-CTR?) with HMAC-SHA256 in encrypt-then-MAC, and the keys $k_u$ and $k_m$ are 512-bit keys split into 256-bit halves for AES and HMAC-SHA256 (resp.). This is all done so that you can change the user's password without re-encrypting the large message. Is that right? – Squeamish Ossifrage Jul 27 '17 at 21:26
  • @SqueamishOssifrage Yes. That's the general idea. (Though I didn't specify that the AES and MAC passwords are necessarily from one password, nor that they are password-based.) – ispiro Jul 27 '17 at 21:31
  • @SqueamishOssifrage As for AES-CTR - .net does not support it natively and I would rather avoid both 3rd party and (of course) implementing it myself. – ispiro Jul 27 '17 at 21:33
  • Read up on HKDF and other key-based key derivation functions (KDFs). A KDF takes a master key and some metadata as input, and outputs subkeys that are deterministically derived from the master. Instead of using your data key to encrypt the data directly, you'd feed it to HKDF-expand to produce two subkeys, one for encryption and one for MAC. (Or, actually, just use an AEAD instead of rolling your own.) – Luis Casillas Jul 27 '17 at 21:40
  • Also, if you're on .NET, you should consider using Inferno. – Luis Casillas Jul 27 '17 at 21:42
  • @LuisCasillas Thanks. I've actually simplified this question, focusing only on the question at hand. (See my old questions regarding what you're referring to.) As for 3rd party libraries - that's not an option at the moment. – ispiro Jul 27 '17 at 21:43
  • Judging based on a cursory glance at that Microsoft documentation, I would stay far away from whatever library that is. Any library that exposes (a) a choice of block cipher, and then (b) a choice of mode in which to use the block cipher, in that orientation, is unlikely to be fit for application development and probably has many trigger-happy foot-guns lurking from the unfortunately not quite bygone '90s era of crypto engineering. If that's your only feasible option in this context, my condolences! – Squeamish Ossifrage Jul 27 '17 at 22:06

1 Answers1

2

$\newcommand{\EtM}{\mathit{EtM}}\newcommand{\concat}{\mathop{\Vert}}$Fix a secret-key message encryption scheme $E(k, n, m)$ and a secret-key message authentication code $M(k, n, m)$, which you combine using encrypt-then-MAC by $$\EtM(k_0, k_1, n, m) = E(k_0, n, m)\concat M(k_1, n, E(k_0, n, m)).$$ Is it safe to store $$n\concat\EtM(k_0, k_1, n, k_0'\concat k_1')\concat n'\concat\EtM(k_0', k_1', n', m)$$ for some long message $m$, so that you can swap out $k_0$ and $k_1$ without having to re-encrypt anything under the long-term keys $k_0'$ and $k_1'$?

Generally, yes—assuming all the keys are chosen independently uniformly at random, the security contracts of $E$, $M$, and encrypt-then-MAC are satisfied, provided you pick a different nonce $n$ each time (and unpredictably, if $E$ is AES-CBC).

You can also reduce the storage needed for keys from (say) a 512-bit concatenation of two 256-bit keys down to a single 256-bit key, by deriving $k_0$ and $k_1$ from some single swappable key $k$, and $k_0'$ and $k_1'$ from some single long-term key $k'$, using a key derivation function such as HKDF or the ‘SHAKE’ extendable output functions (‘XOFs’) of SHA-3 or similar.

Or you could just use NaCl crypto_secretbox_xsalsa20poly1305 or libsodium crypto_secretbox_xsalsa20poly1305 instead of cooking up your own authenticated-encryption out of a block cipher and HMAC. (AES-GCM may not be a good choice here because I infer from context that you probably don't have an easy way to pick $n$ sequentially, and the AES-GCM nonce is not large enough to pick safely at random.)

Squeamish Ossifrage
  • 48,392
  • 3
  • 116
  • 223
  • a) Thanks. b) the security contracts ... are satisfied - that in itself is not proof. Consider someone encrypting and signing using the same RSA keys - though their contracts are satisfied - it's not safe. I'm ignoring the insecurity of using raw RSA. I'm just making a point that sometimes two "secure" things might interfere. – ispiro Jul 27 '17 at 22:08
  • In this case, the contracts are still satisfied because the keys for different purposes are independently distributed. We never reuse any key for more than one purpose here. When you abuse RSA twice to do two different things with the same key, then you have likely violated its security contract and you have to negotiate a new one, just as the answer you cited explains about padding modes that make message representatives disjoint for signature and encryption purposes. You're right that this is not a proof, though: this is a heuristic crypto engineering argument, which is a lot less work! – Squeamish Ossifrage Jul 27 '17 at 22:14
  • I did not mean to complain that I wasn't supplied a proof, of course. I hope it didn't come across that way. I just meant to point out one thing. Thanks again. – ispiro Jul 27 '17 at 22:21
  • @ispiro: No worries, not taken as a complaint. Just acknowledging that I don't have a nice glib proof of a reduction to the security of $E$ or $M$ or an estimate of its tightness. – Squeamish Ossifrage Jul 27 '17 at 22:28