I would like to know how to store a sensitive file; a credential of sorts. I want to password-protect it, obviously. It would be appropriate - in my application - to prompt the user for the password each run. There are proper apps - like SSH - that password-protect private keys and so on, and that's the model and best-practice I'd like to follow.

What is the best-practice for encrypting small files? I'm thinking of generating a random key to encrypt the file with and using a block cipher. And then encrypting this random key with the user's password, and trying to salt and stretch that password.

In the same way that storing password hashes is something you should turn to a proper 'stretching' function like bcrypt/scrypt/PBKDF2 (ideally via a library like Python's passlib) rather than rolling your own, are there proper algorithms and libraries for password-protecting files?


migrated from stackoverflow.com Sep 7 '12 at 22:47

This question came from our site for professional and enthusiast programmers.


The most important best practice in cryptography is: Don't invent your own algorithm, and to a lesser degree, don't invent your own protocol. An encrypted file format is a protocol.

Use an established format, like the OpenPGP message format, for your files. (This does support password-based encryption, too.)

This has the main advantage:

  • You can be quite sure that it is correct, i.e. no mistakes in the design which would allow easy cryptanalysis. (Not 100% sure, but at least a lot more eyes looked at it than will ever look at your own protocol.)

Another nice bonus is that your customers then are able to use the encrypted files also without your program, if necessary (e.g. when your program is not available on the system, has bugs, gets lost, or similar).

  • $\begingroup$ +1 for linking to a complete interoperable best-practice standard for encrypting files -- OpenPGP -- rather than mentioning one particular primitive or another, which all too often are used incorrectly or at least in unnecessarily incompatible ways. $\endgroup$ – David Cary Nov 13 '12 at 13:21

A properly salted cryptographic hash of the password, generated through a secure and slow algorithm such as bcrypt or scrypt, could be directly used as your key (assuming they have the correct size). Salts can be generated randomly on encryption and should be included with the ciphertext.

Bcrypt, for instance, generates a hash of 192 bits (if I am not mistaken); so you could use it directly as an AES key.

If the hash is longer than the size of the key of the desired encryption algorithm you should simply be able to take the first n bits of the hash.

Only encrypting a random key with your password, as you describe, is a redundant extra step that doesn't really add any security.

  • 2
    $\begingroup$ +1 In fact, deriving encryption keys from passwords is the primary purpose of PBKDF2 and its ilk; the name stands for Password Based Key Derivation Function, version 2. The fact that they can also be used for user authentication is just a side benefit. $\endgroup$ – Ilmari Karonen Sep 7 '12 at 20:53
  • $\begingroup$ Ps. While encrypting a random key with the password-derived key indeed doesn't provide a security benefit, it can be convenient if you ever want to change the password (or allow the file to be decrypted with more than one password or other key). $\endgroup$ – Ilmari Karonen Sep 7 '12 at 20:56
  • 1
    $\begingroup$ Good point. Altough I do think the case where different passwords are used to encrypt the same file with the same key are relatively rare. Using this method to make changing passwords cheaper might indeed be a pretty good idea when dealing with very large files or entire backups. $\endgroup$ – AardvarkSoup Sep 7 '12 at 21:17

Read Try to avoid using passwords as encryption keys.

Deriving a cryptographic key from a password tends to be a major security problem, as in practice, passwords rarely have enough entropy to resist offline dictionary attack.

If you absolutely must derive your crypto key from a password, then for heaven's sake, use a slow hash like PBKDF2. But even then, given what we know about typical user behavior, you should expect that this scheme may not provide strong protection against attack.

(I recommend PBKDF2 instead of bcrypt, as PBKDF2 was designed exactly for this purpose. You might be able to adapt bcrypt to use it for this purpose, but you might have to do a little bit of extra tweaking to disable the salt and make sure you use the proper range of bits of the output of bcrypt.)


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.