First up: this is a question about a concept that I try to wrap my head around; it is not about the specific implementation. Anyway…
I have the following scenario (simplified to show the problem I have with the concept):
- I have a symmetric master-key, lets assume the strongest algorithm out there at the time you read this: $KM$.
- I have a bunch of PDF files that have to be encrypted with $KM$.
- As a security feature it is defined that, for every PDF, $KM$ and the $filename$ are shoved into a publicly known function $derive(KM, filename)$ to get a file-specific key $KF$.
- I now proceed to encrypt all the documents with these keys.
Does this add to security or does it just pose a dangerous risk?
The one pro argument I get to hear:
Not all files are encrypted with the same key - it is harder to guess the key.
- So I need to solve $derive(KM, filename)$.
- I have the $filename$ and know $derive$. Which leaves me with one equation with one variable – solvable for $KM$.
The only catch I see is: it will take a little longer to brute force a key, as I have to solve the equation for every key I try. If I brute-force offline, this seems more like a minor inconvenience but not a problem – I will only have to solve for one PDF though, as I can get knowledge $KM$. So, as opposed to forward secrecy, cracking one PDF will crack them all.
The big problem I see:
Losing the $filename$, loses the file. If all chains break, all backups fail and the $filename$ is changed, I cannot for the life of me decrypt the files. I would have to brute-force the master-key, which gracefully I'ld only have to do with one file as described in the previous paragraph.
Additions:
As Maarten Bodewes pointed out in a comment at Stack Overflow question (before this question was moved here):
If a Password Based KDF is used then it is possible to adjust to load factor for derivation. Furthermore, if you would use ${KM}$ directly you would also need to derive or store an Initialization Vector. If the size of the files is not an issue, you could however make this scheme more secure by using hybrid encryption using a public/private key pair, and possibly a MAC. In that case you may not need a KDF (but you would need a secure random generator).
(emphasis mine)
An IV is still generated and stored in the first X bytes of the encrypted document. This does not, however effect the overall concept I think, since he wrote:
If the size of the files is not an issue, you could however make this scheme more secure by using hybrid encryption using a public/private key pair
The whole encryption takes place in a HSM that, for the sake of this question, protects the master-key 100% - you cannot in any way get the master-key in any way other than brute-forcing. But these remarks are not what i was aiming to get as an answer.
The process is as follows:
- User sends a file, encrypted with a ephemeralKey, wrapped with a publicKey only the HSM knows the privateKey for.
- The HSM decrypts the file, genrates $KD$ using the $filename$ and $KM$ only known to the HSM, encrypts the file and stored the file on a harddrive.
- When a user asks for a file, the HSM will generate a ephemeralKey, generate $KD$ from the filename and $KM$, decrypt the file, encrypt it with the ephemeral Key, wrapt the key for the user and send the wrapped key and the file to the user. - $KD$ is never used by anyone but the HSM.
As an admin one does have direct access to the harddrive where the files are stored - does the derivation significantly slow me down if i offline bruteforce a file and, using this $KD$ to solve the derivation function for $KM$?
So:
- PRO: brute-forcing will take marginally longer.
- CON: no real gain like forward secrecy, additional risk.
Wrapping it up…
I generate a derived key for every document via$KD = KDF * KM * filename$ where $KDF$ and $filename$ are known to the public. If I brute-force a document and get the correct $KD$, I know 3 out of 4 variables and therefore know $KM$. As a result, I’m able to derive every $KD$.
This makes me ask: does the whole scheme actually add any security at all?