Zero Knowledge Password Proof: why is hashing the password on the client side not a ZKP?
Your example removes the notion of hashing altogether: H(S+P) becomes a cleartext password that can directly be reused without any extra work.
The main problem of your protocol is that the client's 2nd answer is vulnerable to replay attacks. During the login procedure, an attacker learns u
and h
which can both be reused later in a malicious login by the attacker and will result in a successful login.
I'd recommend using challenge-response authentication with HMAC here, which means the client receives a challenge from the server and returns the HMAC signed challenge (= response).
- Assuming the client knows the password, the client is able to sign messages with it (symetrically using HMAC)
- From the server point of view, the client authenticates itself by signing a message given from the server
Naive protocol to understand the idea:
1. [C] –––(username)–––> [S]
Attacker: learns username (you might want to change that eventually)
2. Server calculates M = (nonce) and stores M
nonce
: a bunch of random bytes which MUST be unique, prevents replay attacks. To make it unique, append a timestamp or login counter for example.
2. [C] <––– M ––– [S]
Passive attacker: The attacker learns M which is different for every login attempt, even for the same user. Without knowing the password, the attacker cannot sign it.
Active attacker: manipulating M doesn't help anything: The client will sign the wrong M which won't be accepted by the server later.
3. [C] ––– HMAC(M, pw) –––> [S]
Passive attacker: learns the signature HMAC(M,pw). The HMAC signature cannot be reused because M is always different (this is why it must be unique).
Active attacker: Manipulating M or the HMAC signature causes the signature to be invalid or not matching the server-stored M in step 4.
4. Server examines if the received M equals the stored M and verifies the HMAC signature
This is possible because the server also knows the password.
This protocol satisfies my interpretation of wikipedia's very loose definition of ZKPP as it is interactive and the client proofs knowledge of password-derived data and not the password itself.
Generally, the security level of zero knowledge proofs is based on iterative procedures which my naive attempt doesn't cover. I'd recommend to take a look at CHAP and/or SRP.