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.

2 Answers2

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.

Serge Ballesta
  • 25,636
  • 4
  • 42
  • 84
  • 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 https://en.wikipedia.org/wiki/Crypt_(Unix)#Relationship_to_password_hash_function and https://en.wikipedia.org/wiki/Crypt_(C)". The actual algorithm is explained here: https://en.wikipedia.org/wiki/Crypt_(C)#Traditional_DES-based_scheme – Royce Williams Feb 02 '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 02 '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 02 '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 02 '18 at 16:10
  • @AndrolGenhald Ah, fair point! – Royce Williams Feb 02 '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.

Royce Williams
  • 9,128
  • 1
  • 31
  • 55
  • 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 04 '18 at 02: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 04 '18 at 15:58