• caglararli@hotmail.com
  • 05386281520

Is password-based encryption better than traditional password hashing?

Çağlar Arlı      -    2 Views

Is password-based encryption better than traditional password hashing?

I have a theoretical question regarding the comparison of password-based encryption and password hashing. Not sure if Stackoverflow or crypto is the best place, but this is more on the side of programming and API/database/application security, so figuring here works best.

First, let me define the two. These are my current understandings, and if my assumptions are wrong, please correct me.

  • Password-based encryption: Uses a password-based key derivation function (PBKDF) to stretch a password into an encryption key (examples are Argon2, PBKDF2, bcrypt, scrypt). This key is then used for encryption/decryption schemes (AES, or other algorithm).
  • Password hashing: Uses a password in a hashing function (similarly: Argon2 PBKDF2, bcrypt, scrypt, or even more insecure password hashing functions like SHA256). Passwords are validated by hashing and comparing outputs.

Now, for most standard applications, the typical accepted practice is something as follows:

  1. User creates an account (email, password)
  2. The password is hashed (let’s say using Argon2) and this is stored in the database (the used salt is stored as part of the Argon2 hash output).
  3. Upon login, the user’s entered password is compared to the stored hash. Specifically, the hash is retrieved from the database, salt is extracted (and reused) and then hashing is performed using said salt and password to see if the outputs match. If they do, the login is a success.

My question stems from a different approach to this traditional user authentication implementation using password-based encryption.

Let’s define a database schema as follows.

| email(varchar) | salt (varchar) | data(blob) |

Now, let’s reimagine the authentication flow:

  1. User creates an account (email, password)
  2. The password is turned into a key using PBKDF (once again, Argon2 in this scenario). The salt used for this key derivation is stored in the database along with the user’s email.
  3. The generated key is used to encrypt some arbitrary data using a stream cipher (so we do not need to worry about padding) such as ChaCha20. This arbitrary data could be something like JSON containing user data or just a plaintext message. The resulting encryption ciphertext is stored in data along with user email and salt.
  4. Upon login, the user’s salt is extracted and used in conjunction with Argon2 to regenerate the key and decrypt the data. If decryption is successful, we have now validated the user’s password.

In this scenario, there are a couple of positive implications that I see:

  • Encryption at rest: If this is necessary for your application, you can just store your user attributes in the data column. If it isn’t necessary, then you can have columns separate from email, salt, and data.
  • Breach protection: If the database is breached (say through some web application logic vulnerability like SQL injection), then there is no hash to crack with tools like Hashcat. Instead, it’s an encrypted blob and the parameters to get there are hidden in server logic (is it Argon2? Bcrypt? AES? ChaCha20). The complexity and time required to try and figure out is not feasible. Compared to typical hash storage which is pretty trivial to determine the logic used (example Argon2 hash: $argon2id$v=19$m=65536,t=3,p=4$JHO1a6fFZyLFgdZ10BBdLw$2bXgltb0IC6JPz02Vb2Gn7DHTzHEdO5v1Zj2fK6lFDw

Of course, I do see a potential implication:

  • Performance? Adds some overhead with encryption/decryption, but I feel on modern systems this is negligible.

But overall, from this (albeit basic) scenario, it seems like the password-based encryption scenario is more secure.

With all of that laid out, I’m interested to know how this approach sounds from an actual application security perspective. Any assumptions that I made that are incorrect? Security & performance implications? Pros & cons of one approach vs. the other? If it is truly more secure, why do more authentication frameworks not take this approach?

Like I said in the preface, I know this is a bit crypto heavy but I think this errs more on the application side of crypto rather than the theory.