# How to encrypt a file for random access

I am a programmer familiar with C/C++ and Python. Lately, we got an assignment from a team asking us to work on one of their projects: we need to make a small program to encrypt a large file using symmetric key encryption. We could easily achieve this using AES128 or AES256 in CRT mode.

The catch however is that if a small part of the file is given along with the location of that bytes from the beginning of the file we should be able to decrypt just that piece.

We thought cutting the file into multiple pieces and applying separate generated key for each but the issue is that regarding what we can do if the said part is not exactly a slice of the size we cut it into. Also would like to know if two over lapping such blocks can be handle.

The idea we are currently working on is this:

• We are slicing into 128 bytes each.
• Calculate number of bytes from the last slice. So if we get bytes from 10 to 128. It will be 9.
• Generate a random padding of 9 bytes at the beginning and then decrypt it. Then remove the first 9 Bytes.
• In case multiple slices overlap they are split and the method is repeated.

So, what I would like to know is if this is sensible or if there's a better cipher or algorithm that allows this.

PS:

1. The files will be image files or document files.
2. Only know some basics of cryptography.
• I am new to crypto. I would like to use the AES128 SRT mode to achieve this. What I want to know is if it is possible. The last two few paragraphs explain my current idea want to know if that would work. – BaxDemon Aug 17 '14 at 18:00
• Oh look somebody hit why I didn't exactly specify full disk encryption in crypto.stackexchange.com/questions/25304/… – Joshua Aug 3 '15 at 15:15

The catch how ever is that if a small part of the file is given along with the location of that bytes from the beginning of the file we should be able to decrypt just that piece.

Normal CTR mode encryption allows one to decrypt any block of the file independent of the rest, so no need to invent your own mode. With AES the block size is always 128 bits, so you can start decrypting from any multiple of 16 bytes. You only need to use the correct counter value.

If you need to start from an offset not a multiple of the block size, you will not need the previous bytes in the block to decrypt it correctly, you can just throw away the initial bytes of the keystream, i.e. truncate $AES_k(c)$ to the rightmost bytes.

You basically want a full disk encryption mode for a block cipher; XTS mode seems to be the current standard. In your case each "disk block" is actually a file offset.

Note that using a stream cipher or counter mode is NOT secure if the data is ever modified in the file, as it would violate the cardinal sin of using the same key and initialization vector to encrypt different messages. This is why fancier modes like XTS were created.

CTR mode could be secure if the file were encrypted exactly once per (key,IV) and was then read-only or append-only. However, going that route would involve a massive rewrite and data migration if your requirements ever changed. So find a respected library that implements XTS mode, do not write it yourself as you are not a cryptographer.

Failing that, I would strongly consider punting and using whatever OS-level file or volume encryption system do its job, such as EFS/BitLocker on Windows or eCryptfs/dm-crypt on Linux. All modern OS have such facilities. Even if you might need some platform specific code or configuration, it would be a massive time-saver and isolate the crypto layer from your application.

• Good point about needing another mode if the file has to be randomly writable as well. – otus Aug 20 '14 at 5:58
• Can you recommend a good C or C++ library that implements XTS? – Ben J Aug 26 '14 at 9:43
• The library version of OpenSSL includes XTS, and Apple's open source version is here opensource.apple.com/source/xnu/xnu-1699.26.8/bsd/crypto/aes/…. And of course all the FLOSS disk encryption tools that support XTS have an implementation. – rmalayter Aug 26 '14 at 14:42
• Commenting on my own answer after some further research in this area... Apparently there are a lot of reasons that "block encryption" is bad (mostly because it is unauthenticated). See sockpuppet.org/blog/2014/04/30/you-dont-want-xts – rmalayter Feb 26 '15 at 17:25