Reputation: 182
I'm building a web application and need to authenticate a user with a user password. I'm trying to build it to what would be considered a good security practice in 2021. As far as I've been able to gather from what I've read online, the following would be expected from sending the password from the client to the server over HTTPS (only).
[Edit: Context about the server] On the server side I intend to store a salt per user and a hashed version of their password. On the wire I obviously shouldn't send the clear text password, but also, to prevent playbacks, I shouldn't send the hashed password value either. Hence the client side algorithm below. [End edit]
Here is my experimental sample code:
public const int HASH_SIZE = 24; // size in bytes
public const int ITERATIONS = 100000; // number of pbkdf2 iterations
public const int NONCE_SIZE = 8; // size in bytes
public static string PasswordFlow(string userPassword, byte[] userSalt)
{
// Hash the user password + user salt
var hpwd = KeyDerivation.Pbkdf2(userPassword, userSalt, KeyDerivationPrf.HMACSHA512, ITERATIONS, HASH_SIZE);
// Generate an 8 byte nonce using RNGCryptoServiceProvider
RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
byte[] nonce = new byte[NONCE_SIZE];
rng.GetBytes(nonce);
// Hash the hpwd byte[] converted to Base64 with the nonce byte array as salt
var final = KeyDerivation.Pbkdf2(Convert.ToBase64String(hpwd), nonce, KeyDerivationPrf.HMACSHA512, ITERATIONS, HASH_SIZE);
return Convert.ToBase64String(nonce)+"$"+ Convert.ToBase64String(final);
}
I would appreciate thoughts on the process above. Did I misunderstand it, screw it up or miss anything? I'm also trying to understand:
I'm not a security expert and I'm also a C# noob so please excuse any blunders.
Upvotes: 0
Views: 643
Reputation: 271
PBKDF2 is designed to reduce brute-force attacks by increasing computational cost. It is not intended to resolve problem of sending plaintext password - this should be done by other security mechanism - secure communication (i.e. TLS 1.3).
If secure communication is broken, then it does not matter if you have sent plaintext or hash of the password.
What you are referring as NONCE should be called SALT.
Basically, PBKFD2:
So, answering your questions:
Upvotes: 2