Password hashing using HMACSHA512 in application

👤 Diwas Poudel    🕒 31 May 2023    📁 TECH

Storing passwords in plain text in a database is very dangerous because anyone who looked through the database would be able to just read the passwords and if your password may be compromised so your application can be at risk. So, it is better to hash the password and store hashed form password in a database so that if your hashed password is compromised, then they don't expose your password. So, a password is a critical part of any web application.

Prevention is better than cure, so the correct precautions are better before your data become exposed. So, we the developer is responsible to take the right precautions!

So, without wasting time, lets them use the best approach for storing password :


Hashing a password is the best approach to storing passwords. Hashing is the practice of using an algorithm to map data of any size to a fixed length. There are many hashing functions like Hash functions like SHA256, SHA512, RipeMD, and whirlpool, HMAC256, HMAC512, etc.


Let’s take a common hashing algorithm SHA-512 and apply HMAC in C#.

1)Create Model as :  UserForRegisterDTO.cs

public class UserForRegisterDTO   {    [Required]    public string Username { get; set; }    public string Password { get; set; }    public int id { get; set; }    public byte[] PasswordHash { get; set; }    public byte[] PasswordSalt { get; set; }   }

2) Creating Register Action inside AccountController

 [AllowAnonymous]    public ActionResult Register()    {      return View();    }      [HttpPost]    [AllowAnonymous]    [ValidateAntiForgeryToken]    public ActionResult Register(UserForRegisterDTO model)    {        User user = new User();        byte[] passwordHash, passwordSalt;        CreatePasswordHash(model.Password,out passwordHash,out passwordSalt);        user.passwordsalt = passwordSalt;        user.passwordhash = passwordHash;        user.username = model.Username;        db.SaveChanges();        return View(model);    }      [NonAction]    private void CreatePasswordHash(string password, out byte[] passwordHash, out byte[] passwordSalt)    {        using (var hmac = new System.Security.Cryptography.HMACSHA512())        {          passwordSalt = hmac.Key;          passwordHash = hmac.ComputeHash(System.Text.Encoding.UTF8.GetBytes(password));        }    }

3) View of Register Action: register.cshtml

@{      ViewBag.Title = "Register";    }    <div class="row">    <div class="col-lg-4" >      <h3>Register</h3>        <form role="form" action="/account/register" method="post">          @Html.AntiForgeryToken()            <div class="form-group">             <input type="text" class="form-control" placeholder="Username" name="Username" required="">            </div>              <div class="form-group">            <input type="password" class="form-control" placeholder="Password" name="Password" required="">          </div>        <button type="submit" class="btn btn-primary block full-width m-b">Register</button>      </form>    </div>   </div>

Register User Page

Here, I have registered user "Diwas Poudel"

User "Diwas Poudel registered successfully". Let's look at Postgresql. 

Created User : You can see in Postgresql
fig. Created User successfully in Postgresql

Let's log in to the same user

4) Let's create Login Action Method in Account Controller.

public ActionResult Login(UserForLoginDTO user)   {      var data = db.User.FirstOrDefault(x =>x.username == user.UserName);      if(data == null)      {        return View(user);      }        if (!VerifyPasswordHash(user.Password, data.passwordhash, data.passwordsalt))        return View(user);      else {        return Redirect("/home")        }    }       [NonAction]   private bool VerifyPasswordHash(string password, byte[] passwordHash, byte[] passwordSalt)   {     using(var hmac = new System.Security.Cryptography.HMACSHA512(passwordSalt))     {        var computedHash = hmac.ComputeHash(System.Text.Encoding.UTF8.GetBytes(password));          for (int i = 0; i < computedHash.Length; i++)        {          if (computedHash[i] != passwordHash[i]) return false;        }          return true;      }    }

5) View of Login as Login.cshtml

@{      ViewBag.Title = "Login";    }    <div>    <div><h2>Simple Login Form</h2></div>      <form  method="post" action="/Account/Login">      @Html.AntiForgeryToken()      <div style="padding-left:8px;padding-right:8px">        <div class="form-group">          <input type="text" class="form-control" placeholder="Username" name="UserName" required="">        </div>    <div class="form-group">        <input type="password" class="form-control" placeholder="Password" name="Password" required="">    </div>        <button type="submit" class="btn btn-primary">Login</button>      </div>   </form>  </div>  
Simple Login Form
fig. Simple Login Form

Let's just visualize it :

A hash of "a" using HMAC SHA 512 produces:






The hash of "" using HMAC SHA 512 produces:





In both outputs is of  128-digit hexadecimal number.