Encrypting text file line by line with stable encryption I want to store files in a secure manner (i.e. no one should be able to decrypt the contents of the file without the secret key) but I also want a diff tool to be able to show me which lines changed (let's assume that you can't learn anything about the content of the file by seeing which lines have changed).

The idea is to encrypt each line individually and convert the result to hex or BASE64 and then write each line into one file. A line with a certain content should always return the same output, no matter where it is in the file.

Specifically, I want a version control tool like Git or Mercurial to be able to efficiently handle the files as text. At the same time, a (self written) UI should be able to show a decrypted diff without the need of decrypting the data inside of the version control tool (git diff would show me the line numbers which I could then decrypt in my app to display them myself).

Is that possible? Do you know where I can find more information how to do this?
Yes, it's possible. Encrypting each line independently, like you suggest is the way to go.

Most likely you will want to use a symmetric encryption algorithm independently for each line – i.e. have a new unique IV/nonce per line. That's the simplest to implement. However, it means every line is up to 128 bits longer. If you can't live with that, you practically have to either sacrifice some security (e.g. use ECB mode without semantic security) or have changes to one line affect nearby lines as well.

One question to consider is whether to use authenticated encryption to guard against an attacker being able to modify the file. This is usually the way to go, but if you have something that ensures integrity at a higher level in your setup (signed tags/commits, say), you could afford to skip it.

For authenticated encryption you need to further decide whether you want a single MAC for the whole file (slower, since it needs to be recalculated after every modification) or one per line (which takes even more space).



In practice, I would go with AES for encryption. (Either 128-bit or 256-bit keys – doesn't matter much in practice.)


If you can live with the extra space it requires, the absolute simplest from an implementation standpoint (when you have a library that supports it), is to use AES in GCM mode. You get both encryption and authentication in one, and the only requirement for IVs is uniqueness. Each line will be up to 256 bits longer (when using 128 bits for both IV and auth. tag).
If you have authentication already, I would go with AES CTR. If you know the file will never have more that $2^k$ lines through its lifetime (counting each version of each line) you could store a $k$-bit value per line instead of a full 128-bit IV. You will need to make sure you never reuse a counter value in any case, including different "forks" of the file.
If you need a MAC for the file, you can do the above and append an HMAC.