c# - 如果我添加随机盐,如何检查密码是否正确?

标签 c# database hash passwords salt

我正在尝试保护我的 C# 应用程序。我知道我们必须将密码哈希和盐存储在数据库中。所以我的问题是:如果我使用随机盐,如何比较密码是否正确?(随机盐每次都会给出随机值)。 我还有下面的代码

 public static string HashPassword(string p, string s)
    {
        var combinedPassword = String.Concat(p, s);
        var sha256 = new SHA512Managed();
        var bytes = UTF8Encoding.UTF8.GetBytes(combinedPassword);
        var hash = sha256.ComputeHash(bytes);
        return Convert.ToBase64String(hash);
    }

    public static String GetRandomSalt()
    {
        var random = new RNGCryptoServiceProvider();
        var salt = new Byte[1024];
        random.GetBytes(salt);
        return Convert.ToBase64String(salt);
    }

总的来说,我愿意接受其他建议。

最佳答案

I am open to other suggestions in general.

我将在这篇文章的序言中提出一个广泛的观点,但我相信它已被广泛持有,不构成“意见”。

如果您这样做是“为了保护您的应用程序”,请立即停止。有更好的解决方案,例如 BCrypt、Scrypt 和 Argon,它们可以为您处理所有这些问题,并防止大多数人甚至没有考虑到的威胁。当然,这些内部包含盐,因此了解它们的用途以及它们的工作原理仍然是一项有用的努力。对于大约相同数量的代码,您处理凭据的安全性将比发布的代码所示的高。谷歌他们的详细信息。

如果您只是将其作为“了解其工作原理的练习”,请继续阅读。

那么盐到底是什么以及为什么它对于保护安全有用?

盐是额外的熵,它不是用户密码的一部分,而是在对密码进行散列和存储时为服务器所知或发明的。验证您的密码时,服务器必须知道生成的盐。它的存储方式有很多种。它可能是存储在数据库中的密码哈希的第一个/最后一个/中间/每 8 个/任意 n 个字符。它可能有自己独立的领域。它甚至可能基于其他不可变的事实,例如用户记录本身的主键。

它所防范的威胁模型可以这样描述。考虑一个已被泄露且现在被恶意行为者持有的数据库。挑战在于,鉴于恶意行为者持有凭据(以散列形式),我们能否阻止他们猜测人们的密码(至少不尝试某种字典或强力猜测攻击。

如果您认为散列解决了该问题,那么我将给出两种可能的情况:

<强>1。两个用户可以使用相同的密码

如果密码经过哈希处理但未加盐,则选择相同密码的两个用户最终将得到相同的哈希值。即使密码不是“可怕的”,其他用户也可能通过他们输入的“密码提示”来泄露您的密码。如果密码被加盐,那么密码提示泄露了其他用户的密码这一事实并不会泄露相同的密码可以在您的帐户上使用的事实。

<强>2。彩虹表

如果您有足够的时间和计算能力,您可以生成(或下载)一组彩虹表。这些基本上是键值对,其中键是哈希值,值是原始密码。这些是反向生成的。也就是说,取一个字符串,对其进行哈希处理,将哈希值作为键,将原始字符串作为目标。要查找,您只需查找哈希键并查看返回的值。近在即刻。不过,如果原始字符串足够长,它就不会被预先计算,因此它不会在彩虹表中出现。如果我知道你使用的盐和哈希算法,我仍然可以进行自己的字典攻击或暴力攻击,但突然我需要依次尝试每个猜测,直到我幸运,所以如果你的密码是好的,我不会在“合理的时间”内找到它。

您提出的问题的准确答案

How I can compare that password is correct if I use Random salt?

您的验证过程需要知道或导出为哈希过程选择的确切盐值。盐可能是随机生成的,但如果是这样,则需要记录所使用的确切值。

关于c# - 如果我添加随机盐,如何检查密码是否正确?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54323344/

相关文章:

c# - 不存在从 DbType UInt64 到已知 SqlDbType 的映射。 Dapper C#

perl - 为什么 Autovivification 发生在 keys() 而不是 %{..} ?

python - 如何使 python 数据类可哈希?

c# - 如何在 UWP 应用程序中隐藏/折叠标题栏?

C# - 如何根据特定值设置 ComboBox selectedItem?

mysql - 自动更新具有自增外键的MySQL关联表

mysql - 无法建立数据库连接

Android开发云数据库

security - 散列和加密算法之间的根本区别

c# - 从大型数据集中获取样本集