简体   繁体   中英

Client Server Authentication

I am creating a client server communication based on Asynchronous Sockets, my client will send the username and password to the server then the server will replay whether the account is valid, so i want to secure this steps so no one could record the conversation and keep sending it to my client to achieve illegal entry to the secret data

[The Question {Simplified}] How to securely authenticate the client to the server ... ?

[NOTE] I know SSL but i cant afford paying for a certificate so i need a free alternative to provide secure communication between my client and server.

As always, the most secure password is the one, that the server doesn't know, and that is never transmitted. So what you could do is:

  • On the server, store the username, a random salt ("account salt") and a secure hash of the salted password ("server shared secret").
  • On login, in a first step let the client transmit only the username (not secret)
  • The server should reply with the account salt (not secret) and a randomly generated session salt (not secret). It is important, that the server generates the session salt.
  • On the client, salt the password with the account salt and hash it (keep this as " client shared secret"), then salt the result with the session salt and hash it again. Transmit this as an authentication token (not secret)
  • On the server, take the salted hash from your DB, salt it with the session salt and hash it - if this matches the authentication token, the connection is authenticated. (Client is authenticated to server)

  • if you want to additionaly authenticate the server to the client, you repeat the procedure: Client generates a salt, server creates token from it by salting/hashing the stored secret.

  • If you want to authenticate the single requests (not only the connection), salt them with the shared secret and hash them, send this as a per-request authentication field. Since in a valid login server shared secret and client shared secret are identical,both sides should come to the same result, thus verifying the authentication field.

在此输入图像描述

I typically tell people that if they find themselves doing crypto themselves they are inventing security problems. :) The odds are good you're missing edge cases. I would suggest relying on something that exists already and has been heavily secured.

If you're using managed sockets, there is a version of the stream class that does crypto for you (NegotiateStream). I would suggest starting there and seeing if it can do what you need w/o you having to invent your own.

You could use a combination of public and symmetric keys in order to secure authentication.

First send a public key for the client to send his authentication data encrypted in. If the data is valid, you could then have the client generate his own public key, and have both send symmetric keys to each other via each other's public key.

Something like that should work.

I know that this was posted a few years ago, but I thought that I would add my own two cents here now. Things have changed in the last couple of year. This might help some one else.

I do not want to take anything away from Eugen, excellent work.

The best way to encrypt the traffic between your client and your server is still using SSL/TLS. You can now get free licenses from https://letsencrypt.org/ .

It sounds like you already had SSL figured out, so I would plug in with the free certs that you get from the above link

Good luck, - Andrew

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM