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:


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


  • 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 at 7: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 at 14:34
  • Before trying to show you're better that everyone else, have a look at already existing solutions and how they work. – MechMK1 May 17 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 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 at 1:01

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.