Ok guys just a small game:
I have some specifications for a project. At some point they ask for the following to encrypt a password over the net, saying that it is a challenge response protocol:
CLIENT ----------------------------- SERVER (1)ask for challenge --------------> (2) <---------------------------- send SHA1 taken from the time (this is the challenge) (3) make SHA1 xor PASSWORD --------> if it's equal to SHA1 xor stored password (4) <---------------------------- Grant access
For those who don't know it SHA stands for Secure Hashing Algorithm, a standard algorithm for cryptography.
I hope it's clear. Question is: If I sniff packets 2 and 3 (the "challenge" and the "challenge xor password", I do have the actual password just with another xor between them both!?!? There is other way to implement this kind of protocol??
How about the following:
- Server sends a random challenge
- Client sends SHA1 checksum of (challenge+password)
- Servers compares against SHA1 checksum of (challenge+stored password)
You would be able to reverse engineer the password. You want to send the SHA of the password, not the password itself. Rolling your own security protocols is almost never a good idea. Can you not use SSL or something equivalent?
That's a pretty horrible protocol. If this is something someone wants you to implement, refuse to. There are existing, vetted protocols for this type of thing. If this is a game where you point out all the flaws - okay.
- Anyone who hears steps 2 & 3 knows the password
- Anyone who hears step 3 and notes the time can brute-force the password if he has any idea of the precision of the time on the server
- I can pretend to be a server (arp poisoning, dns rediction, etc), and get your password, never completing step 4 and feigning a timeout
- Vulnerable to Man in the Middle Attacks because there's no shared secret between client/server or certificates on the server
- Relies on the server storing the SHA1(time) and waiting for a response, so I can overload the server with requests for challenges and never reply.
And I'm definetly missing some more.
You are right -- if you capture the challenge and (challenge XOR password) then extracting the password is easy.
You need to use proper encryption in step 3, not XOR. Encrypt the challenge with the password.
To make an attacker's life harder you could add random data to what you encrypt to: e.g. encrypt paddingCHALLENGEpadding. The server doesn't care what the padding is, it knows where to look for the challenge, but it means an attacker won't know what the whole plaintext is.
As the other's have pointed out, you are correct. Also keep in mind that someone could intercept communication (3) and potentially resend it while the real user is experiencing network issues (eg: a DDOS), the impostor would then be logged in and often that is sufficient to change the password (that is, many systems don't require that you supply a password inorder to change it once you are logged in).
You may want to consider HMAC (keyed-Hash Message Authentication Code). I've blogged about it in detail here: http://blog.ciscavate.org/2007/09/creating-a-secure-webauth-system-part-1-hmac.html and I'll give a quick summary below.
HMAC is a method of ensuring that a message was generated by someone with access to a shared secret. HMAC makes use of some sort of one-way hashing function (like MD5 or SHA-1) to encrypt the secret along with a message. This generates a short digest of 16-20 bytes that acts as a fingerprint of the message+secret combination. When the digest is sent along with the message, the receiver (our server) can re-generate the hash with the same HMAC calculation and compare the locally generated digest with the digest that came along with the message. Remember: the server has the secret too, so it has enough information to confirm the digest. (This only considers the problem of verifying the origin of a message, but you can use the same approach to encrypt the entire message, if you use a different secret, say a set of public keys.)
The way I would do this is the following:
- Challenge the server.
Server responds with it's public key (for, say RSA encryption) digitally signed.
Client verifies PK, and encrypts password with the key, then digitally signs the encrypted password.
Server verifies signing and decrypts the password to store/check it.
The digital signing is important here as it acts as the beginning of preventing man in the middle attacks.
As others have pointed out, yes, this is a poor challenge response algorithm.
You probably want to check out Digest Authentication, as used by HTTP. In fact, if your protocol is over HTTP, you can skip writing your own and just use or implement this.
public key encryption? Use the server's public key to encrypt the password.
Although it is never a good solution to roll out your own cryptographic protocol, and it is something I would not suggest....
To overcome the problem that you are facing... F - A function which takes in the password and a pseudorandom monotonically increasing value and returns a number. For e.g. Hash(Hash(Password) ^ Timestamp)
- Server : Ask for Challenge, Send (Timestamp). Remember Last Timestamp Sent.
- Client, Send Response (Send F(Password, Timestamp) and Timestamp)
- Server: Check Client by using Hash(Password) and Timestamp sent by the client (> Timestamp sent in Challenge).
- If Client is correct, grant access.
- Ensure present timestamp is greater than all client sent timestamps before next challenge to prevent replay attacks.
Kind regards, Ashish Sharma
I believe the Diffie-hellman is a well-known and solid key exchange protocol?
来源:https://stackoverflow.com/questions/188043/security-cryptography-stupid-challenge-response-protocol