Ad hoc…
What you’re describing is not much different from the encryption in storage systems… only that your “storage system” is a file (foo.txt
) instead of a hard drive. Now, in a perfect world you would encrypt every block of data (that you store in foo.txt
) with its own key, but that would be pretty impractical in your situation. From my point of view, the most obvious solution would be to use a “tweakable cipher” or a “tweakable narrow-block encryption mode”. They were designed to avoid (read: work around the problem) the “need separate key per stored data block”.
Therefore, and relying on your description, I’ld most probably opt-in for a “tweakable narrow-block encryption mode” like LRW (paper), XEX (paper), or XTS. An example representing one of the more frequently used implementations would be AES-XTS. Depending on your coding skills, it shouldn’t be all too hard to incorporate such a solution into the CRUD functionalities of your application.
But, it depends on the details…
For the sake of completeness, let me mention that there are other options out there, which might also lead to a valuable solution. I merely mentioned what I personally would tend to use, based on the information you provided. But choosing a fitting solution will strongly depend on things like the kind of data you want to store, how it’s formatted, what security level you expect, what specific scenario is to be assumed, etc. (Always check for potential attack vectors!) You will have to assess and verify all the little details to be able to choose a most optimal solution that perfectly fits your individual situation and needs.
One of many examples: If the filesize and available hardware capabilities permit it, you might be better off handling encryption/decryption on the whole file (using AES-CBC or something like that) instead of crypting the individual data-blocks you plan to create, read, update and delete. On the other hand, if we’re talking about a file that is bound to hold hundreds of thousands of individual data blocks/entries, and which therefore is bound to grow up to and beyond several gigabytes in filesize, loading that beast into system memory to wrangle with contained data will tend to be a bit… (let’s just call it) “non-optimal”.