0

please do not mark this as a duplicate because I've already checked multiple posts but none of them helped me.

Asp.net MVC - How to hash password

Hash and salt passwords in C#

I'm building a website that has a login page, and I read this post

https://www.codeproject.com/Articles/704865/Salted-Password-Hashing-Doing-it-Right#normalhashing

on how to make my login secure.

Now I understand that on each sign up I have to create CSPRNGs(Cryptographically secure pseudorandom number generator) and add it to the password submitted by the user, then hash this mix and store it in the DB, and store the salt for each user because it's a random one for each user. My question is what is the easiest and the most simple way to do that.

In my controller I'm taking the username and the password via this method

public JsonResult Login(LoginModel data)
{  
   //some code...
   //...
}

My login model contain

public class LoginModel
{
    public string Username { get; set; }
    public string Password { get; set; }
}

so I'm getting the username and password like (string a = data.Username, ...)

I already added this to my project but I don't know how to continue from here

using System.Security.Cryptography;

I know how to save in the DB for sure I just want to know, how to make a random salt (maybe using RNGCryptoServiceProvider), and how to add it to the user's password, and then hash the final result. Thanks for any help.

Rehan Shah
  • 1,505
  • 12
  • 28
riario
  • 51
  • 3
  • 11

3 Answers3

5

The answer to every "How do I securely hash passwords" question is the same: YOU DON'T. You're in the business of making unique websites, not in the security business. You don't know what you're doing, and you won't recognize if you're doing something wrong. Until your database leaks out in one way or another, and then you're too late to do anything about it, compromising your users' security.

You use well-researched, battle-hardened, maintained code to store user logins. When you're on ASP.NET MVC, you use ASP.NET Identity. You DO NOT roll your own. Period.

CodeCaster
  • 147,647
  • 23
  • 218
  • 272
3

You could go about adding salt and hashing the password by using a method such as this. Here we send a method a string. This is basically how entity framework hash's a password when you create a user using the login section.

    public static string EncodePassword(string password)
    {
        byte[] salt;
        byte[] buffer2;
        if (password == null)
        {
            throw new ArgumentNullException("password");
        }
        using (Rfc2898DeriveBytes bytes = new Rfc2898DeriveBytes(password, 0x10, 0x3e8))
        {
            salt = bytes.Salt;
            buffer2 = bytes.GetBytes(0x20);
        }
        byte[] dst = new byte[0x31];
        Buffer.BlockCopy(salt, 0, dst, 1, 0x10);
        Buffer.BlockCopy(buffer2, 0, dst, 0x11, 0x20);
        return Convert.ToBase64String(dst);
    }//Entity Framework default way 

The above uses using System.Security.Cryptography; and system.Buffer

JamesS
  • 2,167
  • 1
  • 11
  • 29
  • Thanks for replying, but i wonder why you're using buffer,is there any way to just get the salt into a string,and add the password to it and the the hashed will be stored in db as a string too. – riario Feb 14 '19 at 12:22
  • 2
    @riario the intention is using *slow salted hash*, it is necessary to use reasonable number of iterations to slow down brute-force search. You may as well search internet for PBKDF2, Argon2 or brypt algorithm to store the passwords (indeed RFC2898 defined PBKDF2 as a standard) – gusto2 Feb 14 '19 at 13:06
  • 1
    @riario Don't shy away from raw binary data. Password hashes are, by nature, raw binary data, not strings. You should treat them as such. – Luke Joshua Park Feb 14 '19 at 19:45
-1

I did this way, and it's working fine.

I added a new class

public class Helper
{

    public String CreateSalt(int size)
    {
        var rng = new RNGCryptoServiceProvider();
        var buff = new byte[size];
        rng.GetBytes(buff);
        return Convert.ToBase64String(buff);
    }
    public String GenerateSha256Hash(string input, string salt)
    {
        byte[] bytes = System.Text.Encoding.UTF8.GetBytes(input + salt);
        SHA256Managed shaString = new SHA256Managed();
        byte[] hash = shaString.ComputeHash(bytes);

        return BitConverter.ToString(hash);
    }

}

}

And in my controller I added an instance of this class

Helper myHelper = new Helper();

Then I'm passing values to

string salt = myHelper.CreateSalt(5);
string hashedPassword = myHelper.GenerateSha256Hash(*PasswordField*, salt);
hashedPassword = hashedPassword.Replace("-", string.Empty).Substring(0, 16);

I'm removing the "-"from the hashed password and then I'm taking the first 16 characters.

Thanks to @Luke Joshua Park, @gusto2 , @JamesS and @CodeCaster for their help.

riario
  • 51
  • 3
  • 11