You are not logged in.
Pages: 1
TRestServerAuthenticationDefault.Auth
Join([aClientNonce, User.LogonName, User.PasswordHashHexa], salt);
innerHash = TAuthUser.PasswordHashHexa
PassWord = Sha256(ModelRoot+Nonce+ClientNonce+UserName+innerHash)If the PasswordHashHexa password in the database is compromised (without needing to know the original password), it appears that frontend login is still possible!
Last edited by testgary (2025-11-05 07:48:05)
Offline
Your remark makes perfect sense.
It currently lacks a "client proof" as in SCRAM.
What we could easily do is, in pseudo code:
SaltedPassword = KDF(Password, randomsalt, iterations) // using MCF prefix parameters
// initial server storage
ClientKey = HMAC(SaltedPassword,"Client Key")
StoredKey = H(ClientKey)
ServerKey = HMAC(SaltedPassword,"Server Key")
PersistedKey = "#MCF prefix" + base64uri(StoredKey + ServerKey)
save PersistedKey in the DB for this user
// client side
ClientKey = HMAC(SaltedPassword,"Client Key")
StoredKey = H(ClientKey)
ClientSignature = HMAC(StoredKey, AuthMessage) // here AuthMessage = model.root + username + client nonce + server nonce
return ClientProof = ClientKey XOR ClientSignature
// server side
ClientSignature = HMAC(StoredKey, AuthMessage) // we would try both current and previous server nonce
candidate_ClientKey = ClientProof XOR ClientSignature
Checks: H(candidate_ClientKey) = StoredKey
return ServerProof = ServerKey XOR ClientSignature
// client side
ServerKey = HMAC(SaltedPassword,"Server Key")
Checks: ServerProof XOR ClientSignature = ServerKeyI guess this could be implemented in TRestServerAuthenticationDefault.CheckPassword and TRestClientAuthenticationDefault.ClientComputeSessionKey methods, with proper backward compatibility.
But we would need to store not the crypto hash in PasswordHashHexa, but PersistedKey on server side - this is a breaking change, so we propose to use the # prefix instead of $ for such values. ![]()
And it would also need a new ModularCryptStoredKey() to compute the StoredKey, still with the modular crypt parameters prefix.
Could you please create an issue on GitHub about this?
Offline
Offline
This feature has been implemented in the last hours.
Now TAuthUser.SetPassword() with the TModularCryptFormat overload will use and store the new #mcfformat$scramserverauth format, with proper auto-recognition on the client side. It is the new preferred way of setting a password, and safely authenticate from a mORMot client.
We will officially introduce this in the upcoming 2.4 release of mORMot.
Now our authentication scheme is at SCRAM level, and even a bit safer, thanks to the per-user hashing at DB level.
Offline
Pages: 1