2
$\begingroup$
I'm not a 'cryptographic' anything, so if this is a super-dumb question please let me know (politely).

So here's the deal, say I don't want to store passwords because that opens me up to all sorts of failures (see: Facebook). Instead, I want to use the passwords as a key for something else.

Let's assume our process is:

  1. User enters a password, we use 2FA, so we use that password to DECRYPT (via some KDF + et. al.) the Phone Number or Email (whatever the 2FA calls for here), and start the 2FA process;
  2. User passes 2FA, we log them in;

Now, my thought is that this should be an acceptable process, but I'm not a cryptographic expert on anything, so I'm curious on whether this is an adequate method of storing the password + 2FA component. It seems reasonable, after all, we're no longer actually storing the password, and with a sufficiently-strong KDF we add another layer of security by not using the raw password in the encryption process, meaning if someone manages to break it (let's say we use something like AES-256, or whatever the de-facto standard is) and extract the key, they have the KDF-transformed key, not the raw key.

Additionally, my thought here is that this solves the following problems:

  1. Storing the password in plain-text (obviously);
  2. Abusing the MFA components (as a certain, nameless, company has starting using that Phone Number for marketing purposes);

Does this make sense? Am I talking about something the world / experts have decided is a terrible idea?

$\endgroup$
  • $\begingroup$ Why not store strongly hashed password? $\endgroup$ – mikeazo Mar 22 at 12:59
  • $\begingroup$ @mikeazo I do (I use PBKDF2 with large salts and high iteration counts), but let's assume I don't even want to store the password anywhere, that the only acceptable option is as a secret key to another "thing". (No hashing, no "encrypting" the password, no plain-text...none of it.) $\endgroup$ – Der Kommissar Mar 22 at 13:01
  • 1
    $\begingroup$ You need information to be able to trust anything. Trusting something without information storage is therefore bunk. In your scheme you may need to store the resulting key, for instance. You could however store a single certificate and verify a signature and take the PKI / asymmetric route. $\endgroup$ – Maarten Bodewes Mar 22 at 13:11
  • $\begingroup$ use SRP en.m.wikipedia.org/wiki/Secure_Remote_Password_protocol to perform a zero-knowledge password proof. here is one written in js but there are others for other languages npmjs.com/package/thinbus-srp $\endgroup$ – simbo1905 Apr 6 at 18:38
2
$\begingroup$

It kind of makes sense, but there are some hairy details.


To use a password as a key you need a password based key derivation function or PBKDF, not just any KDF. Otherwise the adversary can try and guess the password and try to decrypt anything you encrypted with it. Generally that would take just one additional block decrypt, so that's generally a fast operation. So you need a work factor (or, for specific PBKDF's, iteration count) to make it harder to guess the password. Just like when storing a password hash, for the same reason you will probably also want to a salt. The salt / random may also be required to stop replay attacks.

This does however mean that the user suddenly has to perform the work factor; generally password hashes are calculated server side. This might be an issue if the client has limited computing facilities - or battery life / heat dissipation issues, etc.. More importantly, if the attacker learns the key from your DB, then the attacker can simply skip the calculation altogether.


Generally we don't encrypt known / public data. It may be easy to slightly alter the data by adversaries, which in turn may result in surprising attacks. Generally we use a MAC such as HMAC over the data instead. That way you can verify if the key is correct by simply validating the MAC.


There are many other ways to verify passwords. For instance, you could have a look at PAKE protocols or SRP.

You haven't really indicated why simply storing a password hash is not sufficient either. Currently you are making your life more difficult without making your protocol more secure.

$\endgroup$
  • $\begingroup$ Currently I PBKDF2 with 50k+ iterations and 16-byte salts, at a minimum (we store HASH + SALT + ITERATIONCOUNT and up the iterations usually 2-3k per year). I am just curious on how this particular facet would look (and whether it's useful or not). $\endgroup$ – Der Kommissar Mar 22 at 13:17
  • $\begingroup$ That sounds good. I hope I've put enough info in my answer to make it worth your while. As it stands, it's not good, but there may be tricks to make it better. However, as you can see, this kind of stuff is pretty tricky to get right, and using something that has already been standardized should be strongly recommended, especially if you're not a cryptographer. $\endgroup$ – Maarten Bodewes Mar 22 at 13:42
  • $\begingroup$ Only one more curiosity: would this change if we salted the "MFA" component being encrypted? (We can ignore the salt for our purposes, but keep it to make the encrypted data look more random.) I wouldn't think it would help, but am now curious. $\endgroup$ – Der Kommissar Mar 22 at 13:59
  • $\begingroup$ No, the work factor is for the password -> key derivation. I don't see how using a salt (IV?) for the encryption would make any difference. $\endgroup$ – Maarten Bodewes Mar 22 at 22:31

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.