1

I'm mainly trying to verify large file chunks which are encrypted each alone with a different key/salt/nonce for each chunk then appended to the whole file in the end to form 1 file.

One thing I wanted to implement was the principle of not outputting plain data of any chunk to the user unless every chunk of the file authenticates successfully. If 1 fails, the whole operation fails.

To do this, if the file has multiple chunks, I do 1 pass to authenticate all chunks, then another pass to decrypt them if the first pass authenticates.

I'm using the library provided by .net to do this and it seems to output the plain chunk to a span if that chunk authenticates which would technically put the decrypted chunk in memory, technically allowing someone to see what's happening in the memory for the time it is there. How am I supposed to ONLY authenticate without doing any output whatsoever to any destination, and can that library do it somehow (i.e. am I missing anything?) or should I use another library that provides this functionality?

It seems very odd to me that this is the behaviour, compare it to a group of people standing outside your door, you ask their ID one by one but it doesn't mean that will let them enter automatically if they verify successfully.. maybe you want the full group in at once..

Elie-M
  • 23
  • 4

1 Answers1

1

I'm mainly trying to verify large file chunks which are encrypted each alone with a different key/salt/nonce for each chunk then appended to the whole file in the end to form 1 file.

This sounds very inefficient. In fact, it sounds like what you're doing may not be linking the chunks together at all, which would be a vulnerability.

You need to ensure that:

  1. The file cannot be truncated.
  2. None of the chunks can be reordered or duplicated.

The first can be accomplished by including the length of the entire file in the associated data of the first chunk. Alternatively, you can use something like the STREAM construction, but that's slightly more complicated. It's used by projects like age.

The second can be done using a counter nonce or by including the previous authentication tag in the associated data of the next chunk.

I would recommend incrementing the nonce for a given key and using a unique key for each file. The initial nonce can be 0 or random.

One thing I wanted to implement was the principle of not outputting plain data of any chunk to the user unless every chunk of the file authenticates successfully. If 1 fails, the whole operation fails.

You should either:

  1. Use HMAC-SHA256 or HMAC-SHA512 over the entire file (if you want to stick with the .NET library). BLAKE2b or BLAKE3 would be faster. However, this really defeats the entire point of using AES-GCM in my opinion, and you'd be better off just doing Encrypt-then-MAC for each chunk, which would offer committing security.
  2. Don't authenticate the entire file before decrypting the first chunk. Instead, you simply throw an error and erase all of the output when verification for a chunk fails.

I would recommend 2, regardless of whether you want to use AES-GCM or Encrypt-then-MAC.

samuel-lucas6
  • 2,211
  • 9
  • 20