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)
  • 1
    $\begingroup$ Is there any particular reason you want to use AES for this (such as it is the only cryptographic algorithm implemented on the device and you can't implement anything else, such as some hash algorithm and password based key derivation schemes)? $\endgroup$ – Henrick Hellström May 5 '13 at 10:49
  • $\begingroup$ Yes, there is some limitations for using one-way hash $\endgroup$ – Ehsan Khodarahmi May 5 '13 at 10:54
  • 1
    $\begingroup$ See Thomas Pornin's answer here, AES has issues with related keys and so should not be used in this context. If you really must do this, I would suggest encrypting a 16-byte constant instead and using that to check. The attacker will get a plaintext-ciphertext pair for free, but that should not be a problem provided the rest of your cryptographic scheme (if any) is designed properly (without these types of constraints). Preferably, use this "key" only for authentication. $\endgroup$ – Thomas May 5 '13 at 11:29
  • $\begingroup$ However this may not be valid depending on your needs as it is somewhat malleable (but then, so is your scheme to some extent). $\endgroup$ – Thomas May 5 '13 at 11:34
  • 1
    $\begingroup$ Is this homework? There's a tag for that. Hint: how much CPU.time would it take to find the password using an implementation of AES based on this, assuming the password is the first one described here? Compare with proper use of scrypt. $\endgroup$ – fgrieu May 5 '13 at 16:30

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.

  • 1
    $\begingroup$ This would normally be correct but the OP stated his requirements, namely that only AES was available on the target platform (this is a very real limitation on embedded systems) - see Henrick's comment. $\endgroup$ – Thomas May 5 '13 at 15:12
  • $\begingroup$ @Thomas, well, the OP did not state that any such requirement in his question, and his one comment on the subject is pretty vague. So I'm not very clear on what the requirements actually are. I think this is a good first answer; the OP should start by looking at these standard schemes, and if they can't be used, be clearer about why not. $\endgroup$ – D.W. May 5 '13 at 20:27

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.


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.


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.