0

I'm developing a pretty standard program which lets users save their work in a custom file format and reopen it later. Now I'd like to add the capability to encrypt the file using a user-defined password and I wonder what steps to take and what technologies to use.

From what I've read on the subject I think I need some way to derive an encryption key from the password, as well as some sort symmetric encryption algorithm which will be used to encrypt the relevant file content. There needs to be some unencrypted data in the file out of necessity (magic/version number, encryption parameters/salts/IVs) as well as some way to verify that those unencrypted parameters have not been tampered with. Finally, on decrypting the file we need some way to verify that the entered password was indeed correct, without introducing a potential attack vector.

So what steps should I take to achieve this?

Which technologies should I use?

What should be the general design of the file format?

The result should be secure enough by today's standards for a target audience of private users and small companies.

5
  • 3
    Use a pre-made library supporting AES or similar. Crypto is hard and it's easy to make a minor error in implementation that results in it not working properly. This is still possible with a pre-made library, but at least the encryption part should work. There is a guideline in crypto software: don't roll your own unless you really know what you're doing, and even then, try not to.
    – Matthew
    Jun 6, 2016 at 10:10
  • 1
    "So what steps should I take" ... If you have to ask, then you should not be considering re-inventing the wheel. Do as @Matthew says, there are a handful of high-quality pre-made libraries out there, use them. Jun 6, 2016 at 10:15
  • 1
    @LittleCode: Since I'm asking which technologies to use I'm obviously not planning to 'reinvent the wheel', but planning to use already well-established algorithms which (hopefully) can be found in any good crypto-library. I'm simply asking which ones I should use, and how to combine them in order to not open up any vulnerabilities. If there are good libraries which also abstract the task of combining everything together even better - please let me know which ones I should look at. But obviously I still need to know how everything works together - at least on a meta/high level point of view.
    – Askaga
    Jun 6, 2016 at 10:33
  • 2
    @Askaga, I'm afraid my answer is the same, and you've answered it yourself, i.e. you need to find a library that is sufficiently high-level that you don't need to worry about the low-level details. "I'm simply asking which ones I should use" is an opinion-based question and has no place on StackExchange, but maybe something common like PGP will suit your needs and is probably sufficiently abstracted that you don't need to worry about the details. Jun 6, 2016 at 11:21
  • Have you checked Openssl and its libraries ? U can also find its architecture and good documents using it !! Jun 6, 2016 at 13:27

2 Answers 2

2

It is entirely up to you. In Java for example, there are libraries (cryptographic functions should not be implemented from scratch) for AES encryption that let you use this cipher to encrypt a byte stream with a given key and IV. So most often, even when using libraries, you are still left with the problems you mentioned:

  • Where should meta information be stored? (Version, original file name, original path etc.).
  • Where should the encryption parameters be stored?
  • Where to store IVs
  • Where to store the salt

It really depends on the application you are creating. I would consider storing the essential information (IV, salt) inside the encrypted file in a custom header. Embedding essential information inside the file has the advantage, that all you need to decrypt it is the encrypted file itself and the key.

You could put the meta information inside the header too, or if your application demands it, store it in an external database. Since meta information is non-essential, encrypted files can still be decrypted even if the database becomes corrupt or lost.

There needs to be some unencrypted data in the file out of necessity (magic/version number, encryption parameters/salts/IVs) as well as some way to verify that those unencrypted parameters have not been tampered with.

I'm not sure why exactly you need that, but you could reserve extra space in your custom header for a checksum calculated over IV + encryption parameters. That way you could always tell if the parameters were modified. You could however not restore a corrupt IV for instance, at least not without brute force.

The result should be secure enough by today's standards for a target audience of private users and small companies.

If your encryption algorithm is considered safe and you are handling the user passwords correctly (this is the biggest caveat!!), then there is not much you can do wrong with the file format. IV, salt and encryption parameters can be made public (read: stored in plain text). This should not have an impact on the security of your chosen encryption.

0

I'd recommened you use a time-tested compression library that is capable of strong encryption (AES-128/256) to wrap your entire file.

The reason is that designers of those file formats have already evaluated potential attack vectors and have built them into the format requirements. Libraries implementing those formats thus have a minimum standard to adhere to. The implementations are likely to have received a lot of scrutiny as well.

If the programming language you're using does not have a reputable library fitting above description. You can always shell an external command line utility and pass the data using pipes. You can keep the file extension the same and use magic numbers to check if decompression is necessary.

Not the answer you're looking for? Browse other questions tagged .