views:

363

answers:

2

I am creating a program that needs to store the user's data in encrypted form. The user enters a password before encryption and is required to supply the password again to retrieve the data. Decryption takes a while if there is a lot of data.

Now, I want to check that the user has entered the correct password before doing the decryption. This check needs to be fast, and the decryption process is not.

How can I check the password before actually completing the decryption process ? I thought about storing a hash of the password as the first few bytes of an encrypted file - this would be easy and fast enough - but I am not sure whether it compromises security ?

I am using .NET and the built in cryptography classes.

+7  A: 

Well, a cryptographic hash shouldn't compromise security as long as it is salted and has reasonable complexity; personally, though, I'd probably try to set it up so that data corruption (due to incorrect password) is obvious early on...

Any possibility of injecting checksums in the data at regular intervals? Or if the stream represents records, can you read it with an iterator (IEnumerable<T> etc) so that it reads lazily and breaks early?

(edit) Also - forcing it to decrypt a non-trivial chunk of data (but not the entire stream) before it can tell if the password was right should be enough to make it hard to brute-force. If it only has to work with the first 128 bytes (or whatever) that might be fast enough to make it worth-while trying (dictionary etc). But for regular usage (one try, password either right or wrong) it should have no performance impact.

Marc Gravell
Thanks - I think I will try using a per-record checksum. As you point out, I should be able to detect corruption early on.
driis
+1  A: 

I suppose you are using the password as a salt for the encryption/decryption process. The simplest approach would be to encrypt some standard phrase or may be the password that user provided as the input string with the same password as salt for the encryption process. When the user wants to decrypt the data take that password as salt for your decyption process and use ot to decrypt the encrypted password. If you get the password back then the user has provided the correct password and you can continue the decryption process otherwise notify the user that his password is incorrect.

The process would be:

  • User gived PASSWORD and DATA for enryption.
  • You encrypt the PASSWORD with PASSWORD as the salt. and store it as ENCRYPTED_PASSWORD.
  • Encrypt the DATA with PASSWORD and store it.

The user comes back gives you the PASSWORD.

  • You decrypt ENCRYPTED_PASSWORD with PASSWORD as salt.
  • If the result is equal to PASSWORD you decrypt the DATA otherwise you notify the user.
But encrypting a password (rather than hashing a password) is enough to make me think: "am I doing this right?". Storing an actual password (even encrypted) isn't ideal.
Marc Gravell