4

I am designing a procedure and file format for the encryption application. I came to a point when I need to make a decision regarding the method/workflow of the encryption. I can't make up my mind on pros vs cons of using one approach over another.

Below is an overview of the format structure:

------------------------------------------
| File signature || fixed    | plain     |
|----------------||----------|-----------|
| Algorithm info || fixed    | plain     |
|----------------||----------|-----------|
| Seed           || fixed    | encrypted |
|----------------||----------|-----------|
| Data           || variable | encrypted |
|----------------||----------|-----------|
| CRC            || fixed    | encrypted |
------------------------------------------

Initially, I am going to use SHA-256 for a Hash function and AES-256 for an Encryption algorithm, but later it will be configurable, as the format suggests.

Proposed procedure for creating encrypted container:

  1. Hash(Password) => Key-Pass
  2. Generate random Seed
  3. Key-Pass XOR Seed => Key-Seeded
  4. Encrypt Seed with Key-Pass and store encrypted Seed
  5. Encrypt Data with Key-Seeded and store encrypted Data
  6. Encrypt CRC with Key-Seeded and store encrypted CRC

Questions

A. Do I gain anything from storing encrypted Seed and CRC? Would it be less secure if I store them not encrypted?

B. Is it more or less or no difference in security of using [ Hash(Password + Seed) ] for key generation rather than prosed [ Hash(Password) XOR Seed ] for the final key?

C. A concluding question from two questions above. Would it be better or worse to use the alternative procedure for creating encrypted container:

  1. Hash(Password + Seed) => Key
  2. Store unencrypted Seed
  3. Encrypt Data with Key and store encrypted Data
  4. Store unencrypted CRC (or encrypted)

I guess I would have to store unencrypted Seed in order to regenerate Key on reading back the encrypted content. CRC can be either encrypted or unencrypted.

dezlov
  • 840
  • 8
  • 20

2 Answers2

3

Building your own cryptographic file formats is always tough (and risky).

Key generation Instead of rolling your own key generation routine, please use PBKDF2 (PKCS #5 v2.0, RFC 2898) to generate your keys. This will require you to store the salt (what you are calling a seed) in an unencrypted format.

CRC Storage If you're already at the level of using crypto, don't use CRC for integrity checks. You're already planning on using SHA256 elsewhere, use it for your integrity check as well. (I recommend hashing the unencrypted data and storing the hash unencrypted, though you could encrypt it to if you want.)

Community
  • 1
  • 1
Eadwacer
  • 1,138
  • 7
  • 10
  • I was afraid that I will be referred to RFC 2898, which is very heavy reading. I may get there some day, but for a first stage I wanted to use a simpler approach and find out advantages and disadvantages between different approaches. That is why your answer is not very useful as it does not address any of my questions directly. – dezlov May 25 '11 at 13:52
  • Many languages, platforms, and libraries provide implementations of PBKDF2. I strongly recommend you look through your tools to see if it is already provided to you by your cryptographic libraries. I answered the way I did because I cannot in good consciousness advise people to roll their own cryptographic standards. There are too many ways to get it wrong and StackOverflow isn't a medium where I can really work through all of the necessary details to ensure your strategy is safe. – Eadwacer May 25 '11 at 18:35
0

If you H(password) XOR with the seed, you need to store the seed encrypted, otherwise you will give away the hash. If you give away the hash, people can easily brute force it. That is why salt and a number of iterations is used on most protocols (like PBKDF2).

You should never save the CRC unencrypted since a CRC gives information about the data within the encrypted container. Same as with a hash as Eacwacer suggested. You are better off using a MAC (also generated with the key generator for instance).

As you asked for particular answers, I'll answer your questions below:

A: better store it encrypted B: H(password | seed) is more secure C: difficult to say, the XOR is wrong and the plain CRC too, but I would still go for the second one

And for the unasked one:

D: pretty please with sugar on top, use a well known password based encryption algorithm instead and use a cryptographically secure way of integrity checking

Maarten Bodewes
  • 90,524
  • 13
  • 150
  • 263
  • Thanks for the useful information and answers to my questions. I will follow the alternative procedure, as you suggested. And will investigate PBKDF2/HMAC at a later stage. P.S. Regarding your answer to A, seed/salt will have to be stored unencrypted if following suggestion in B, correct? – dezlov May 25 '11 at 14:09