0

I want to store a password securely on a storage (suppose in a usual unencrypted file).

I use this password as AES key to encrypt itself (using AES-ECB) & then store it on the media (the password length is at most 16 bytes).

When user wants to confirm it's identity, I decrypt this saved encrypted content with user input & compare it with the same input, if they were equal it means that user has authenticated successfully.

Know I've two important questions:

  1. Is it a CORRECT solution? If not, why not?
  2. Is it the BEST solution? If not, why not? (and please give me the better suggestion)
Ehsan Khodarahmi
  • 236
  • 4
  • 12

3 Answers3

3

I think what you are looking for is a Password-Based Key Derivation Function (PBKDF).

You can take a moderately strong password, like 12-14 random letters and numbers (no dictionary words though!), and throw it into the PBKDF function together with some other parameters, e.g. salt, number of iterations and the desired key length.

After that you have a reasonably strong - say 128 bit key - for the real AES encryption/decryption.

For more info, see http://en.wikipedia.org/wiki/PBKDF2

One more thing. To prevent brute forcing of your key you should experiment with the number of iterations for the key derivation. As a good rule of thumb, choose a number that makes the algorithm run for approximately 1 second on the target machine.

TJ_Spark
  • 31
  • 2
2

What you are looking for is a Pseudo Random Function that should be indistinguishable from uniform, even if the key material that is passed to it is not. One potential problem with your scheme is that the AES key schedule is not particularly good at extracting the entropy from keys that are not selected (pseudo-)randomly, such as passwords and pass-phrases. This is e.g. demonstrated by the related key attacks against AES-256. You could fix this by using CBC-MAC with a constant key as key extractor, before you use AES-ECB for "hashing" the password. (A similar technique is e.g. used in FIPS 180-4 for condensing the entropy generated by the entropy source.) That is:

Let $K_0$ be a fixed constant key.

In order to hash a password $P$ (in the form of an octet string) with a 128 bit (unique) salt $S$, do the following:

  1. Pad $P$ with a single octet 0x80 followed by zero up to 15 octets with the value 0x00, to form an octet string $P'$ of a length that is a multiple of 16.
  2. Divide $P'$ into $k$ blocks $p_1...p_k$ of octet length 16. Let $c_0$ be a zero valued block and $p_{k+1} = S$.
  3. For $i$ from 1 to $k+1$, let $c_i = AES_{K_0}(c_{i-1} \oplus p_i)$
  4. Let $K = c_{k+1}$.
  5. Let $h_0$ be a zero valued block.
  6. For $i$ from 1 to $iter$, let $h_i = AES_{K}(h_{i-1})$
  7. Output $h_{iter}$.

Note that the above algorithm introduces three features not mentioned in your question: Firstly, it supports passwords and pass-phrases of arbitrary length. Secondly, it introduces a salt that should be used to prevent an attacker from building a dictionary of common passwords. Thirdly, it introduces an $iter$ parameter that increases the required effort for brute force testing (in particular) low entropy passwords.

Henrick Hellström
  • 10,556
  • 1
  • 32
  • 59
-1

Search for passwords on IT Security and you will find tons of advice on how to store passwords, and how not to. Your scheme is not a good method for hashing passwords: it is a fast hash, it lacks any salt, and it unnecessarily limits the password length. People have studied this at great length: before trying to re-invent the wheel, I suggest you read up on what others have come up with.

D.W.
  • 36,982
  • 13
  • 107
  • 196