1

I am working on a website with accounts and I want a login scheme that does not expose users' passwords or hashes in the event of a total security failure. I would greatly appreciate some feedback on this authentication scheme:

  1. Client retrieves auth challenge from server
  2. Password is hashed to 32 byte integer on client
  3. Integer is used to create a keypair, PK, using static keypair generator
  4. Temporary session key is generated, SK
  5. Challenge is signed with PK
  6. SK.public and challenge signature are encrypted with PK.private and server public key
  7. Cipher is sent to server with username
  8. Server decrypts cipher using associated public key for username, checks challenge signature and allows SK.public to be used for x time

Edit: I'm a fool, this doesn't add any level of security. If the generator is static then it literally has no advantage over a hash. This one was super obvious and I should have caught it, but it's still a good reminder not to try to make new protocols unless you really know what you're doing.

  • 1
    How do you create a PK from the integer in step 2? How does the server know the clients public key - or do you just replace storage of hashed password with storage of public key? And what is so bad to use an **established** hash algorithm specifically designed for password storage **instead of inventing your own** method? See [How to securely hash passwords?](https://security.stackexchange.com/questions/211/how-to-securely-hash-passwords). – Steffen Ullrich Apr 08 '18 at 16:37
  • There are several ways to generate a private key from a static value, I haven't determined what library I'll be using yet I'm just asking about the concept of using a pw hash as a key root. Nothing wrong with using hashes necessarily, I just don't like the idea of user hashes being exposed. I'm not so much inventing my own method as implementing secure methods in a different way, I think. – Sneaky Beaver Apr 08 '18 at 16:41
  • 1
    *"I just don't like the idea of user hashes being exposed"* - exposing a hash created by established password hashing methods does not pose a greater problem than exposing the public key in your method. *" I'm not so much inventing my own method as implementing secure methods in a different way,..."* - Just combining existing methods in your own way does not guarantee security - and yes, you are obviously trying to invent your own method instead of using an established method. Maybe you do this because you don't understand what kind of protection the established method actually offers. – Steffen Ullrich Apr 08 '18 at 16:50
  • See my answer for thoughts on inventing own methods vs. using existing. But the hole I see in the mathematics of the above is generating a private key from a static value, instead of randomly. Randomness is essential to ensure the security of a private key. – nbering Apr 08 '18 at 16:52
  • You're 100% correct Steffen, I'm not a security researcher so making my own scheme probably wouldn't work out too well. Also as far as using a static method, you're totally right nbering. I don't know how I didn't see this earlier but using a static generator is absolutely not any better than hashing. I was somehow thinking that key security > hash security but that only applies if randomness is involved. I think I'll just go with traditional solutions. – Sneaky Beaver Apr 08 '18 at 16:55

2 Answers2

1

Authentication Guidance

OWASP has a Password Storage Cheat Sheet with some excellent guidance on hashing schemes, and the background theory of how they keep the passwords safe. There's also a section covering the piece you seem most concerned about - protecting a user's account in the case of an eventual compromise.

For further reading, Troy Hunt has an article - Passwords Evolved: Authentication Guidance for the Modern Era - that summarizes recent update to government publications on the topic, including NIST Special Publication 800-63 - Digital Identity Guidelines.

Don't Re-Invent the Wheel

It sounds like you are trying to invent something completely new. I would recommend sticking to things that are proven. The above resources should help with that.

It's not that I see anything inherently wrong with your suggestion. I'm not a mathematician or cryptographer myself, so I wouldn't claim to have the expertise to certify your scheme as secure. It just seems like you're doing a lot of extra work, to come up with and implement a non-standard solution, which may actually make it more vulnerable in the end.

Non-standard schemes also have the disadvantage of being harder to maintain as people come on who are not aware of the details of how your scheme was constructed, what factors make it secure, and may make changes that poke holes in your security model.

Lastly, as software developers, we're usually not paid to do security research and invent new encryption or authentication schemes. Our clients or employers pay us to make measurable improvements in the state-of-the-art for their specific domain. This is just my opinion, but when it comes to implementing authentication, it would be almost negligent not to follow the guidance provided by the organizations like NIST, OWASP, and the security teams at the vendors who produce the software and libraries we use (Microsoft, IBM, Oracle, etc).

nbering
  • 3,998
  • 1
  • 21
  • 22
  • Fair enough, I was thinking that since most programs/websites implement their own version of the typical guidance that doing something a little unique using standardized libraries and encryption methods would be acceptable. I understand the logic of just sticking to established authentication schemes though so I suppose I ought to just do that. My main concern was being 100% certain no hashes will ever be dropped but with modern security measures I suppose 99.9% and standardization > 100% and potential other problems. – Sneaky Beaver Apr 08 '18 at 16:51
  • Wow I'm stupid, just realized my method doesn't even protect passwords better than hashing, as both are static methods and hashes are already only broken by brute forcing. – Sneaky Beaver Apr 08 '18 at 16:55
  • Ya, don't beat yourself up too much. It's very tempting to try and play with the cryptographic lego pieces and build something new and interesting. I like to do this stuff in my spare time though, and don't include it in production systems. – nbering Apr 08 '18 at 16:57
0

For this to work, the server needs to store public key generated from the password (i.e. "PK.public"). WIthout that, there is no way for the server to verify the signature.

So now, instead of a table full of hashes you have a table full of public keys derived from passwords. An attacker who got her hands on that table could just do a brute force attack on it, repeating steps #2 and #3 for various passwords until she gets a match. Instead of storing a hash, you are storing something derived from a hash. At best, that is equivalent to just storing the hash.

So all you have done here is add lots of complexity by adding some fancy assymetric crypto, while getting no security improvement at all. Since complexity is your enemy, this is a net loss.

Anders
  • 65,052
  • 24
  • 180
  • 218