I programmed an application on Linux using C, I added an authentication and cryptography layer that's going like this :

1 -client sends connection request. -server send a random challenge to client. -the client adds a salt to the challenge and hash it using SHA1 then sends it. -the server adds the same salt and hash the challenge with SHA1, and compare the received result.

2 -In the positive case, the server asks the client for login and password. -the client sends the login and password(salted and hashed with sha1) . -the server search for the login and hashed password in a file .

3 -If the client has sent a valid login and password, he is authenticated. -A key session is generated by concatenating The hashed challenge received And the hashed password..

4 -the key session is used to encrypt data with AES256

I want you to tell me what do you think about it, Is it secure ? Is there any attacks that can break that sequences in any step...? Thank you so much.

1 Answer 1


Your protocol is quite underspecified, but some remarks can still be made:

  • In the first step, either the "salt" is chosen randomly by the client and sent along with the hash value, in which case this step appears completely useless; or the salt is not sent by the client, but is a pre-shared secret value between client and server, in which case it is not a salt but a key, and the rest of the protocol is completely useless.

  • In the second step, the client sends his login and "hashed password" where the hash uses some salt. If the client always sends the same hash value, then presenting that hash value grants access: it is password-equivalent. Any attacker observing a connection (purely passively) then learns enough to fake the authentication, so the protocol would be utterly weak.

If your protocol has to have any value, then we must assume that things go that way:

  • Client connects; server sends a random value N (technical term is a nonce).
  • Client sends another random value N' to the server (and also sends a hash value computed over the public values N and N'; that hash value serves no useful purpose).
  • Client sends the user name L and the value h(N+N',P) where N and N' are exchanged nonces, P is the user password, and h is a "hash function" which somehow combines N and P (there are a lot of methods to do this combination, many of them being weak in more or less subtle ways).
  • The server has a copy of P and thus can recompute the value h(N+N',P) and see if it matches what the client sent.
  • Client and server use another function h' to compute h'(N,P) and use that value as a shared key to do some symmetric encryption for the rest of the data.

Assuming that you did everything properly and used hash functions in a proper way and did not forget to add integrity checks and took care of the gazillions of implementation details which can plague the best designed protocols, then you will have obtained, at best, TLS-PSK. There are two inherent and unavoidable weaknesses in that protocol:

  • The server must store a password-equivalent secret. If an attacker gains a read-only view of the server data (a usual consequence of SQL injection attacks or stolen backups), then he learns enough to authenticate as any of the registered users. This is considered bad. See this blog post for a discussion on that subject.

  • A passive attacker learns enough to run an offline dictionary attack: the attacker just has to observe one authentication, and then he can "try passwords" on his own machines; he just enumerates possible passwords until he finds one which matches the hash values he observed. This, again, is bad, because passwords tend to be vulnerable to such an exhaustive search. Online dictionary attacks, where the attacker must talk to the genuine server or the genuine client for each password try, are much less a concern, because the server can enforce strict limitations on the number of tries per second; whereas an offline attack is limited only by the computational power that the attacker can muster.

The proper way to do a client-server password-based mutual authentication is to use a password-authenticated key agreement, which results in a shared secret suitable for symmetric encryption with integrity checks. This basically means TLS-SRP. 15 years of implementations and attacks and fixes have demonstrated that designing and implementing a secure protocol of that kind is not easy at all.

  • Hey this was one of the best explanations that I have read, but what stops an attacker to get both the server and the client nonce?
    – jigzat
    Sep 18, 2014 at 19:23

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .