【问题标题】:MVC - How to hash and saltMVC - 如何散列和加盐
【发布时间】:2019-07-23 17:20:36
【问题描述】:

我设法让哈希工作,但盐部分仍然是一个问题。我一直在搜索和测试示例但没有成功。这是我的哈希代码:

        [Required]
        [StringLength(MAX, MinimumLength = 3, ErrorMessage = "min 3, max 50 letters")]
        public string Password { get; set; }
        public string Salt { get; set; }

哈希密码功能(无盐):

 public string HashPass(string password) { 

       byte[] encodedPassword = new UTF8Encoding().GetBytes(password);
       byte[] hash = ((HashAlgorithm) CryptoConfig.CreateFromName("MD5")).ComputeHash(encodedPassword);
       string encoded = BitConverter.ToString(hash).Replace("-", string.Empty).ToLower();

          return encoded;//returns hashed version of password
      }

注册:

        [HttpPost]
        public ActionResult Register(User user) {
            if (ModelState.IsValid) {

                        var u = new User {
                            UserName = user.UserName,                               
                            Password = HashPass(user.Password)//calling hash-method
                        };

                        db.Users.Add(u);
                        db.SaveChanges();

                    return RedirectToAction("Login");
                }
            }return View();    
        }

登录:

     public ActionResult Login() {
            return View();
        }

        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Login(User u) {
            if (ModelState.IsValid) 
            {
                using (UserEntities db = new UserEntities()) {

                    string readHash = HashPass(u.Password);

                    var v = db.Users.Where(a => a.UserName.Equals(u.UserName) &&
                                              a.Password.Equals(readHash)).FirstOrDefault();
                    if (v != null) {

                        return RedirectToAction("Index", "Home"); //after login
                    }
                }
            }return View(u);
        }

到目前为止哈希工作..但是我如何在这里使盐工作?

我更喜欢对我的代码进行演示,因为我发现很难用文字来理解。

我先使用数据库。

【问题讨论】:

  • 有一个很好的例子HERE
  • 这条消息已经回复here.
  • 仅使用散列函数是不够的,仅添加盐对提高安全性无济于事。相反,iIterate over an HMAC with a random salt for about 100ms duration and save the salt with the hash.使用PBKDF2password_hashBcrypt等函数和类似函数。关键是让攻击者花费大量时间通过流行的密码列表暴力查找密码。

标签: c# asp.net-mvc hash


【解决方案1】:

在安全方面,不要试图重新发明轮子。使用基于Claims 的身份验证。

如果您仍然必须管理用户名和密码,请使用基于哈希的消息验证码 (HMAC)

我还建议投资一些时间并阅读Enterprise Security Best Practices。已经有更聪明的人解决了这个问题,为什么要重新发明轮子。 .NET 拥有所有的好东西。

示例如下:

//--------------------MyHmac.cs-------------------
public static class MyHmac
{
    private const int SaltSize = 32;

    public static byte[] GenerateSalt()
    {
        using (var rng = new RNGCryptoServiceProvider())
        {
            var randomNumber = new byte[SaltSize];

            rng.GetBytes(randomNumber);

            return randomNumber;

        }
    }

    public static byte[] ComputeHMAC_SHA256(byte[] data, byte[] salt)
    {
        using (var hmac = new HMACSHA256(salt))
        {
            return hmac.ComputeHash(data);
        }
    }
}



//-------------------Program.cs---------------------------
string orgMsg = "Original Message";
        string otherMsg = "Other Message";


        Console.WriteLine("HMAC SHA256 Demo in .NET");

        Console.WriteLine("----------------------");
        Console.WriteLine();

        var salt = MyHmac.GenerateSalt();

        var hmac1 = MyHmac.ComputeHMAC_SHA256(Encoding.UTF8.GetBytes(orgMsg), salt);
        var hmac2 = MyHmac.ComputeHMAC_SHA256(Encoding.UTF8.GetBytes(otherMsg), salt);


        Console.WriteLine("Original Message Hash:{0}", Convert.ToBase64String(hmac1));
        Console.WriteLine("Other Message Hash:{0}", Convert.ToBase64String(hmac1));

注意:盐不必保密,可以与散列本身一起存储。这是为了增加对rainbow table 攻击的安全性。

【讨论】:

  • 您是说在使用基于声明的安全性时使用盐没有显着意义吗?你提到的关于不重新发明轮子的事情听起来是这样的。请详细说明?
  • 我是说使用现有的库,如 Identity Server 或其他 .NET 解决方案。不要实现你自己的。
【解决方案2】:

使用来自 Microsoft 的 System.Web.Helpers.Crypto NuGet 包。 它会为您处理盐分。

您可以像这样散列密码:var hash = Crypto.HashPassword("foo");

您验证这样的密码:var verified = Crypto.VerifyHashedPassword(hash, "foo");

【讨论】:

  • 您是说在使用您的答案中提到的助手时,盐腌根本不需要手动处理?
  • 应该是正确的。请参阅此处的讨论:stackoverflow.com/questions/17693918/…
  • 问这个问题已经有几年了,我想知道哪些助手是现代 .NET Core 环境的最佳选择(即至少 2.x,最好是 3.x) .我找到了this thingthat thing。不过,两者似乎都不再维护了。您目前使用的是哪个版本的 NuGet?
  • 我看到MSDN 提供了一个关于散列密码的方法,但这与 Crypto 类相去甚远,大多数似乎是手动管理的,这与你的说法相反.这让我害怕我找错树了。请指教。
  • 我们使用的是后者(版本 3.2.7),但我们没有使用 .NET Core。
猜你喜欢
  • 2011-06-02
  • 2011-02-27
  • 2015-02-17
  • 1970-01-01
  • 2015-08-20
  • 2011-10-29
  • 1970-01-01
  • 2012-03-24
相关资源
最近更新 更多