I'm using AES in GCM mode of operation for encryption/decryption & authentication of segments of data in a file. The layout of each segment can be summerized by this diagram. Each segment is basically (enc-)decrypted separately from one another, using their individual (randomly generated) IV and Tag:

enter image description here

The encryption process of such segment is done as follows:

enter image description here

While decryption & auth would be carried out as such:

enter image description here

So let me explain my dilemma.

I'm trying to optimize the situation when one of those segments (pictured above) is deleted. The head-on approach would be to zero it out on disk. But, for the purpose of optimization, I was thinking to delete only its IV and Tag, thus hoping to make decryption of that segment's data computationally infeasible. But this brings up two points:

  1. IV size of 12 bytes seems kinda low for that. I know that that is the default size of the IV for AES-GCM. But would I benefit in this scenario if I increase the IV size to 32 bytes? So that way if I remove a 256-bit IV, will it render the encrypted data "safe to discard"?

  2. Tag itself. Is it used for decryption or just for authentication? In other words if I clear it out for my purpose of discarding the encrypted data, will it even matter. I was playing with the actual function that does AES-GCM decryption (implemented using Crypto++ function named CryptoPP::GCM<CryptoPP::AES>::Decryption::DecryptAndVerify()) and it seems to return different plaintext if I alter the tag, but I'm not 100% sure about it.

  • $\begingroup$ Don't use random nonces or nonce lengths other than 96 bits! AES-GCM security is bad if you do that, because as you get to moderate volumes of data the probability of a security-destroying nonce collision grows rapidly. $\endgroup$ Mar 12 '19 at 1:27
  • $\begingroup$ The nonce is generally not secret. But, if you don't mind the cost of changing keys (which is free if you switch to crypto_secretbox_xsalsa20poly1305, which also has other security advantages and often performance advantages), you could store a secondary key alongside each record, and hash it together with the master key to derive a per-record key; then all you need to erase is the secondary key in order to erase the record. $\endgroup$ Mar 12 '19 at 1:29
  • $\begingroup$ @SqueamishOssifrage: yes, you definitely have a point about the random IV collision. I'm not sure though that Crypto++ supports XSalsa20Poly1305. Plus all my infrastructure (code) is geared towards AES-GCM. It'll be hard to change it. $\endgroup$
    – c00000fd
    Mar 12 '19 at 2:03
  • $\begingroup$ Related: crypto.stackexchange.com/questions/64298/… and crypto.stackexchange.com/questions/64664/… (Those questions are about CTR mode, but since GCM is just CTR+GHASH, the answers apply to GCM as well.) $\endgroup$ Mar 12 '19 at 2:07
  • 1
    $\begingroup$ Possible duplicate of Crypto-shredding a file by erasing the IV instead of erasing the Key $\endgroup$ Mar 12 '19 at 2:08

But, for the purpose of optimization, I was thinking to delete only its IV and Tag, thus hoping to make decryption of that segment's data computationally infeasible.

Neither work. The IV might seem to work (as doing a brute force search over a space of size $2^{96}$ might appear to be daunting), however the attacker has another potential approach.

If an attacker has the ciphertext, has a correct guess to 16 bytes of the plaintext, and the key, he can recover the IV; from there, he can recover the rest of the plaintext.

Because of the likelihood of the attacker guessing 16 bytes of plaintext, this wouldn't appear to be feasible.

And, the tag is even worse (and so is the AAD, in case that occurs to you); an attacker with the key, iv and ciphertext can trivially decrypt the ciphertext without the tag. He might not be certain that the ciphertext hasn't been modified; however he might be willing to assume that it wasn't.

Since I gave you two negative answers, lets give you a positive idea; why don't you make the key generation procedure:

key :=SHA2( master key || extra data )

Where the extra data is stored on in the segment header (and nowhere else); it is generated randomly when you first encrypt; when you decide to do a quick erasure, you overwrite it. The master key is the one derived from the password with PBKDF2.

If this extra data is at least 256 bits long, recovering the key is no easier than attacking AES-256 directly.

  • $\begingroup$ Hah. That sounds like a really good idea. Thanks. I'm ashamed that I haven't thought about it. $\endgroup$
    – c00000fd
    Mar 12 '19 at 1:54
  • 1
    $\begingroup$ @c00000fd: also, to partially make up for the expansion of the header, you don't need to store an IV; you are generating a fresh key each time (because of extra data is always different, even if the password is the same), so you can safely always use a fixed IV (say, the all zero IV) $\endgroup$
    – poncho
    Mar 12 '19 at 1:59
  • $\begingroup$ Oh, wow. I was just mulling over @SqueamishOssifrage's comments to my original post about the possibility of the IV collision if I generate them randomly. So doing that SHA2 trick might solve that as well. $\endgroup$
    – c00000fd
    Mar 12 '19 at 2:02
  • $\begingroup$ Nonce collision is only a problem under the same key. If you never reuse a key, you can use whatever is your favorite number as the nonce, like 87. $\endgroup$ Mar 12 '19 at 2:05
  • $\begingroup$ @SqueamishOssifrage: heck, I'll use 41. Dare me not! (OK, if seriously, thank you guys for your input. I really appreciate it. Love this Crypto branch of Stack Exchange!) $\endgroup$
    – c00000fd
    Mar 12 '19 at 2:08

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.