1

I am trying to figure out how to build a secure, playback-proof, web authentication scheme and at the same time be able to use a KEK at the server.

After a lot of reading it seems that a reasonable way to validate the password between the server and client is as follows:

Server:

  • I have stored db-hash = hash(password, server-user-salt).

Client:

  • Obtain a copy of the server-user-salt
  • User enters user-name, password.
  • [Edit: Get the nonce from the server] Generate a client-nonce
  • Send the server Hash(Hash(password, server-user-salt), client-nonce), client-nonce

The server can then compare the received doubly hased value with Hash(db-hash, client-nonce).

So far so good - hope I didn't misunderstand that part, I'm not a security expert :-D

Now on the server I also need to be able to decrypt another secret key - using a KEK. My initial thought was simply that if I sent the password to the server, I could run it through PBKDF2() and use that as my KEK.

But given the authentication algorithm above, I shouldn't send the password to the server. I probably can't use a hash() function since what the server needs is a secret (e.g. the password) so that it can generate the KEK. I could generate the KEK on the client, but then I'd send the KEK over the wire which is almost as bad as sending the password.

So to combine the authentication scheme above with a KEK would I need to throw myself into a public/private key exchange to send over the secret / password to the server?

  • Please clarify a couple of things : 1) I assume this exchange has the potential to occur un-encrypted(ie. no TLS?) ; 2) your Server will be keeping a history of the value of `client_nonce` to ensure that replay doesn't occur? 3) Can Client remember `server-user-salt` and not ask for it again? – brynk May 17 '21 at 07:45
  • It's over TLS only but I've read you shouldn't rely 100% on it. E.g. firewalls can inspect it AFAIU. Your nonce question made me realize why it's better to generate the nonce on the server and give it to the client :-D thanks. So let's assume in my question that the nonce is generated on the server and passed to the client. 3) no the client doesn't have a reliable storage mechanism and there can be multiple clients (web browsers) for the same user – Michael Seifert May 17 '21 at 14:34
  • Before trying to show you're better that everyone else, have a look at already existing solutions and how they work. –  May 17 '21 at 16:49
  • @MechMK1 I'm not trying to show anything, I'm trying to figure out what is a strong practice in 2021. There is surprisingly little coherent information about it on the web, so I've pieced the above together from everything I read. If you know of a particular standard I can follow I'd love to hear that. – Michael Seifert May 17 '21 at 19:56
  • I think @MechMK1 was referring to me, actually `;)`. You're right about not relying on TLS as *panacea* .. it's job is to secure the transport layer- as distinct from the application layer- and v1.3 goes a long way toward ensuring Server isn't impersonated and Client hasn't been intercepted. (Ignoring MitM-proxy *configured within the browser*!) Having said that, a passive observer won't get much from TLSv1.2+ on-the-wire. Nonces: what if Server is compromised? Can both contribute? (Less chances exist for dishonest behaviour.) Had you considered my Q about Client storing `server-user-salt`? – brynk May 18 '21 at 01:01
  • Reading again, I think my comment came off as a bit rude (okay, maybe a bit a lot rude), so sorry for that. I guess I should not comment when sleep deprived. Anyways, back on-topic: Stick to TLS. It's what everyone uses. And while appeals to authority are generally frowned upon, I'd argue if it's good enough for every tech company out there, it's good enough for you. If you like we can talk more in-depth about what makes it secure, but TLS in general is secure. –  May 18 '21 at 10:45
  • Thanks both. Yes your comment on nonce was very helpful. I've made the server generate it and the client can then use the nonce from the server, apply it to the password hash and send the result back so the server can verify without the password ever leaving the client. – Michael Seifert May 18 '21 at 18:40

0 Answers0