The title sounds way too adventurous for what it actually is. I am currently building a system which features some encryption. There is already a system in place, which is built after that scheme if somebody is interested in more context: https://stackoverflow.com/a/44925718/5395110.

As a next step I have to plan user authentication (typical username-password-login). First I thought of a standard password-hash approach using Argon2i hashing. That sounded reasonable but then I realized that with enough bad luck I would essentially give the attacker a free pass to the data in combination with the already built system. To prevent that I thought of integrating password checking into the existing system and get rid of any hash stored as plaintext.

What I came up with:

  1. User inputs password and sends it to the server
  2. The password gets hashed with Argon2i => hashed password
  3. Hashed password is used to decrypt a AES-256-GCM-secured ciphertext
  4. If the ciphertext can be decrypted and is equal to a known static plaintext then the decryption was successful and the password is valid

So my question: Is a password checking system that uses a password-derived key to decrypt a authenticated block cipher to determine validity a reasonable alternative to just saving the hash?

The advantages are that there is no hash which can be extracted so an attacker would have to first find the key to the AES-container and afterwards find the plaintext to an Argon2i hash which seems like a very unrealistic task.

The bad feeling I have with this method is that it would probably work but completely miss the point of a authenticated block cipher since what I'm essentially doing is generating a HMAC of the hashed password(secret) and the known plaintext reference password(message) in a weird and unnecessary complicated way.

  • $\begingroup$ Why do you actually use a master password and not simply a high-entropy random secret here (which you can print as base64 or hex if humans rarely need to interact)? $\endgroup$
    – SEJPM
    Jul 12, 2017 at 18:40
  • 1
    $\begingroup$ I'm also confused what you hope to gain from this plaintext comparison that you don't already have through the authentication tag? $\endgroup$
    – SEJPM
    Jul 12, 2017 at 18:42
  • $\begingroup$ @SEJPM The term "master password" may be misleading. I'm aware that this "master password" is never read by a human that's why it is a random 256 bit key. It's not a stupid human generated string. And the plaintext check is not (realistically) necessary but I included it in the specs anyway as it is the final assertion since a tag might not catch a wrong password in every case in the edgiest of all cases. $\endgroup$
    – SkryptX
    Jul 12, 2017 at 18:49
  • $\begingroup$ If all users passwords can derive / decrypt the master key doesn't this mean that the master key is only as safe as the weakest user password? This seems like an issue. $\endgroup$ Jul 12, 2017 at 19:07
  • $\begingroup$ This is actually an issue as well as having up to 30 possible passwords that a bruteforce attack can hit, but it is the safest it can get because it is a web application and I have no control over the devices accessing it. Except I'm missing something. I'm open for additional input and ideas to make the system better. $\endgroup$
    – SkryptX
    Jul 12, 2017 at 19:29

2 Answers 2


To be entirely honest the Idea is pretty intresting but wouldn't help a lot. AES is, mainly because it's widely used, a pretty cheap thing to do, so there's basically just one step more after hashing, so it wouldnt make a lot of a difference in that part. but one thing that I think may be intresting would be (but for a different reason):

Not encrypting a static String, but rather use the hash to create or encrypt a random Private Key generated while the user is signing up, while keeping the Pubkey readable and offer it to the user.

If you now use that specific key to sign something (similar to a canary report) and the user can check that it was signed with his key, then he can be relatively sure that for example no password reset happened because one cant reset the password without resetting the keys.

  • 1
    $\begingroup$ Yes it probably doesn't add much more security to the hashing than factor two for bruteforcing. Your other suggestion is interesting indeed. I will consider that for a future release. This seems like a nice addition with a lot of benefits for data integrity and traceability since digital document are a core part of the application. $\endgroup$
    – SkryptX
    Jul 10, 2018 at 19:35
  • $\begingroup$ probably it wouldnt even be factor 2, when you are using something like argon2 to hash which is deliberately slow, in comparison to things like AES, which instead is made to be fast. especially with AES-NI, your decryption is a matter of milli- if not nanoseconds, basically only adding not really much to Argon2 $\endgroup$
    – My1
    Jul 11, 2018 at 7:27

Checking a password against a known static string is a common practice for example in disk encryption programs. I don't see any weakness in your scheme, but I don't think it would increase the security - as My1 already stated.

an attacker would have to first find the key to the AES-container and afterwards find the plaintext to an Argon2i hash which seems like a very unrealistic task.

An attacker would try to find the plaintext for this hash not through cryptoanalysis, but through a dictionary attack. And for a dictionary attack one additional AES decryption of a short string makes no difference. The main problem of weak passwords can't be solved in this way.

If you can keep the salt or an additional random string secret (pepper), this would protect also weak passwords. However, in web applications, this is difficult to implement. Another approach would be to protect the hash against botnet-processed dictionary attacks by using ROM hardness (terabyte-sized lookup tables). Yescrypt provides such a thing, but Yescrypt is other than Argon2i vulnerable to cache timing attacks.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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