【问题标题】:How to hash users passwords?如何散列用户密码?
【发布时间】:2019-02-15 20:52:26
【问题描述】:

请不要将此标记为重复,因为我已经检查了多个帖子,但没有一个对我有帮助。

Asp.net MVC - How to hash password

Hash and salt passwords in C#

我正在建立一个有登录页面的网站,我阅读了这篇文章

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

关于如何确保我的登录安全。

现在我了解到,每次注册时我都必须创建 CSPRNG(加密安全伪随机数生成器) 并将其添加到用户提交的密码中,然后对该组合进行哈希处理并将其存储在数据库中,并为每个用户存储盐,因为它是每个用户的随机盐。我的问题是什么是最简单和最简单的方法。

在我的控制器中,我通过这种方法获取用户名和密码

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

我的登录模型包含

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

所以我得到了用户名和密码,例如 (string a = data.Username, ...)

我已经将此添加到我的项目中,但我不知道如何从这里继续

using System.Security.Cryptography;

我肯定知道如何在数据库中保存我只是想知道,如何制作随机盐(可能使用 RNGCryptoServiceProvider),以及如何将其添加到用户密码中,然后对最终结果进行哈希处理。 感谢您的帮助。

【问题讨论】:

  • 你的 .Net 框架版本是什么?
  • 我觉得吹镖在你链接到的第二篇文章中的回答涵盖了所有这些,并附有一个完整的例子(吹镖在安全性方面非常好;也许随着时间的推移唯一改变的关键是加密算法的选择)(注意:RNGCryptoServiceProvider 上的GetBytes 可以给你随机盐)
  • @karthickj25 4.5
  • @MarcGravell 我要再检查一次。

标签: c# asp.net-mvc encryption


【解决方案1】:

每个“我如何安全地散列密码” 问题的答案都是相同的:你不。您从事的是制作独特网站的业务,而不是安全业务。你不知道自己在做什么,也不会意识到自己做错了什么。直到您的数据库以一种或另一种方式泄漏,然后您再采取任何措施都为时已晚,从而危及用户的安全。

您使用经过充分研究、久经沙场、维护的代码来存储用户登录信息。当你在 ASP.NET MVC 上时,你使用ASP.NET Identity。你不要自己动手。时期。

【讨论】:

    【解决方案2】:

    您可以使用诸如此类的方法来添加盐并对密码进行哈希处理。这里我们向一个方法发送一个字符串。当您使用登录部分创建用户时,这基本上是实体框架散列密码的方式。

        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 
    

    以上用途 using System.Security.Cryptography;system.Buffer

    【讨论】:

    • 感谢您的回复,但我想知道您为什么使用缓冲区,有什么方法可以将盐放入字符串中,然后将密码添加到其中,然后哈希值将存储在数据库中也可以作为字符串。
    • @riario 的意图是使用 slow salted hash,有必要使用合理的迭代次数来减慢暴力搜索。您也可以在互联网上搜索 PBKDF2、Argon2 或 brypt 算法来存储密码(实际上 RFC2898 将 PBKDF2 定义为标准)
    • @riario 不要回避原始二进制数据。密码哈希本质上是原始二进制数据,而不是字符串。你应该这样对待他们。
    【解决方案3】:

    我是这样做的,效果很好。

    我添加了一个新课程

    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);
        }
    
    }
    

    }

    在我的控制器中我添加了这个类的一个实例

    Helper myHelper = new Helper();
    

    然后我将值传递给

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

    我从散列密码中删除“-”,然后取出前 16 个字符。

    感谢 @Luke Joshua Park、@gusto2、@JamesS 和 @CodeCaster 的帮助。

    猜你喜欢
    • 2011-05-10
    • 2013-11-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多