0

I'm curious about validating user passwords (for logins and such). I see that it is common to use a salted hash to store (safely) user passwords with the intent to validate user logins.

My question:

Would using passphrase-protected private keys be an equivalently safe method of doing this?

Possible implementation:

When a user creates an account on your platform they would give you the password they intend to use. The server would then take the password and generate a new private key (based on your choice of entropy) and use the user's password as the passphrase to 'protect' the private key. You would then store the passphrase-protected private key paired with the user name so when someone tries to login with a given (registered) username, you can lookup the private key and try and unlock it with the provided password.

  • 1
    Why would you want to do this? – Xiong Chiamiov Feb 2 '18 at 15:45
2

Ok, let us see what is involved in both case.

  1. Standard salted hash

    On password creation, user gives the clear text password. It is hashed with a secure salted algorythm and only the hash is stored

    On further logins, user gives the clear text password. The salt is extracted from the password store and the hash are compared

    Security heavily relies on the quality of the hashing algorithm, but is a strongly documented point, and on the intrinsic quality of password - read entropy of password generation

  2. Password is used as the password for a private key

    It is basically the same process, the only difference is that the hashing algorithm is replaced with an attempt to unlock a password protected key. It now depends on the encryption algorithm used to encrypt the private key. That is also a strongly documented point.

That means that you have only changed a hashing algorithm with an encrypting one. BTW the original hashing algorithm used in old Unix system was based one the encryption of an all zero bits byte string with the user password with DES(*), not far from your proposal.

TL/DR: it will just depend on the hashing algorithm and the encryption algorithm used to encrypt the private key


(*) It is in fact a bit more complex because the crypt operation was repeated 25 times and perturbated with salt (ref.) - credits to @RoyceWilliams for the precision.

  • The original UNIX crypt hashing algorithm based on DES was not simple encryption - it was a true KDF, with multiple rounds and transformations, and quite different from what's proposed by the OP. Compare en.wikipedia.org/wiki/… and en.wikipedia.org/wiki/Crypt_(C)". The actual algorithm is explained here: en.wikipedia.org/wiki/Crypt_(C)#Traditional_DES-based_scheme – Royce Williams Feb 2 '18 at 15:52
  • 1
    @RoyceWilliams: The linked page does contain That key is then used to encrypt an all-bits-zero block. Ok, the operation is then repeated 25 times but the algorithm is indeed an encryption one. But I have edited my answer with your comment, so thank you very much for it. – Serge Ballesta Feb 2 '18 at 15:53
  • Indeed. Note especially that, unlike what the OP is proposing, UNIX DES crypt(3) is not reversible, by design. The OP's proposal would involve actual decryption as a step. A DES crypt(3) hash cannot be "decrypted" or "reversed". That's why it is quite far from from the OP's proposal. – Royce Williams Feb 2 '18 at 15:59
  • 1
    @RoyceWilliams I don't see how OP's proposal is reversible either. The private key is being decrypted, but you can't get the password from the private key. – AndrolGenhald Feb 2 '18 at 16:10
  • @AndrolGenhald Ah, fair point! – Royce Williams Feb 2 '18 at 16:11
2

Please don't do this.

The two big drawbacks of encrypting passwords rather than hashing them are speed for the attacker and difficulty for the developer to execute safely.

First, true password-hashing algorithms are designed to be very slow. With your proposed method of a single round of encryption, attackers with access to the data can try billions of passwords per second -- and likely bruteforce the passwords of most of your user base.

Second, as soon as you're trying to roll the crypto yourself, it's much easier to make a mistake that can be exploited by an attacker.

It is much safer to use a well-defined, modern hashing algorithm (traditionally pbkdf2 or bcrypt, and more recently scrypt or Argon2) with high work factors.

Pornin answers this question well here.

  • I am using a standard salted hash system, but I am still curious. The link you point at uses symmetric keys, I was thinking of something like RSA with a key length 4096+ (OpenSSL maxes at 16K). Could using long RSA keys act like having a high work factor? – MichaelMitchell Feb 4 '18 at 2:16
  • 1
    Historically, attempts to reinvent proper password hashing fail. People much smarter than either of us have spent a lot of time working on the right way to solve this problem, and encryption isn't it. And no - the slowdown your proposed approach would be insignificant compared to how slow a proper approach would be. For example, attacking bcrypt of cost 12, my 6x GTX 1080 rig can only perform 300 hashes per second. Encryption is designed to not be slow. Proper password hashing is designed to be slow. There's a reason why so many answers tell people not to roll their own. Please don't. – Royce Williams Feb 4 '18 at 15:58

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.