First I need to mention that I can't use BouncyCastle to implement this solution.
I have to encrypt files into the file system. Those files are not going to be tranfered over the wire to any other location. They are only going to be stored in the server for later use by an application installed there. The file system may or may not be encrypted at an OS level, but that's something that I can't count on.
My files are going to be big files (say from several hundreds of megs to some times a couple of GBs). And they will be created on a regular basis, so I can expect to have a growing number of them. Also, sometimes some of this files are going to be deleted cause they may no longer be needed, and some other times files will be kept for years.
I already have the encryption in place, with AES/CBC/PKCS5Padding, using a 256 bit key and I/O Cipher Streams. I have no authentication thought.
I don't think I can assume that it is safe to just encrypt and not use authentication as the server could be hacked I guess and the files stolen.
Also, by reading several questions it's clear that no authentication is just someting I shouldn't even think of.
So what are my options here then? I see 2 with some pro/cons analysis:
Option 1: AES/CBC + MAC (say with SHA-256)
Pros
- Already have the encryption part working
- Supported by Java with no extra libs
Cons
- I have to deal with the computation of the MAC
- I have to deal with appending the mac to the file and extracting it later
- I will have to handle validation myself.
- Lots of room for me not getting that right I'm affraid.
Option 2: Use GCM operation mode
Pros
- Forget about handling tag computation / message authentication
- Supported by Java (I'm using 1.8, so the default provider supports it)
Cons
- I found that there are people who wouldn't recommend it.
- Also this post seems to suggest that performance is somewhat an issue with Java8, but that's something I haven't verified (Update: @archie pointed to here and here that comfirm the performance issues).
- It is badly broken in Java 1.7. I have yet to verify it works ok in Java 1.8 (update: this thread verifies that problems are still present in Java 8)
- I'm using a single symmetric key for encryption. I'm worried about how to manage the nonce so I don't break the security properties of the algorithm (My current implementation gets the IV from cipher.getIV() after the Cipher is initialized. I'm not sure if that's good enough for GCM or if I need to take other special considerations.)
Are those options that I mention valid? What about the pro/con analysis? Is there any other suggestion you would have? Which approach would you choose?