Challenge response outline
Lets assume you have one-way hash function abc
(in practice use md5
or sha1
a cryptographically strong hashing algorithm for PHP see: password_hash).
The password you store in your database is abc(password + salt)
(store the salt
separately)
The server generates a random challenge challenge
and sends it to the client (with the salt
) and calculates the expected response: abc(challenge + abc(password + salt))
The client then calculates: abc(user_password + salt)
and applies the challenge
to get abc(challenge + abc(user_password + salt))
, that is sent to the server and the server can easily verify validity.
This is secure because:
- The password is never sent in plaintext, or stored in plaintext
- The hash value that is sent changes every time (mitigates replay attack)
There are some issues:
How do you know what salt to send? Well, I've never really found a solution for this, but using a deterministic algorithm to turn a username into a salt solves this problem. If the algorithm isn't deterministic an attacker could potentially figure out which username exists and which do not. This does require you to have a username though. Alternatively you could just have a static salt, but I don't know enough about cryptography to assess the quality of that implementation.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…