我正在尝试保护我的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);
}
我一般都会接受其他建议。
答案 0 :(得分:2)
我一般都会接受其他建议。
我将以宽泛的观点作为这篇文章的开头,但我相信它已足够广泛而不会构成“意见”。
如果您正在执行“保护应用程序安全” ,请立即停止。有更好的解决方案,例如BCrypt,Scrypt和Argon,可以为您解决所有这些问题,并防御大多数人甚至没有考虑过的威胁。这些当然在内部包括一种或多种盐,因此了解它们的用途以及如何工作仍然是一项有益的努力。对于大约相同数量的代码,您将比发布的代码更安全地很多处理凭据。在Google上获取详细信息。
如果您只是作为“了解其运作方式的练习” 来这样做,请继续阅读。
那么到底是什么盐?为什么它对保护安全性有用?
盐是附加的熵,它不是用户密码的一部分,而是在哈希值和存储密码时由服务器知道或发明的。验证密码时,服务器必须知道生成的盐。有多种存储方式。它可以是数据库中存储的密码哈希的前/后/中间/每8个/任意n个字符。它可能有其自己的单独字段。它甚至可能基于其他不可更改的事实,例如用户记录本身的主键。
这样可以防御的威胁模型可以这样描述。考虑一个被恶意行为者入侵并拥有的数据库。面临的挑战是,鉴于恶意行为者拥有凭据(以散列形式),我们能否阻止它们猜测人们的密码(至少无需尝试某种字典或蛮力猜测攻击)。
如果您认为哈希解决了该问题,那么我将给出两种可能的情况:
1。两个用户可以使用相同的密码
如果密码是散列的而不是固定的,那么选择相同密码的两个用户将以相同的散列结束。即使密码不是“糟糕的”,其他用户也可能会通过输入“密码提示”来显示您的密码。如果密码很咸,那么密码提示就会泄露其他用户的密码,这一事实并不会泄漏相同的密码可以在您的帐户上使用的事实。
2。彩虹桌
如果您有足够的时间和计算能力,则可以生成(或下载)一组Rainbow表。这些基本上是键值对,其中键是哈希,值是原始密码。这些是反向生成的。也就是说,取一个字符串,对其进行散列,然后将散列添加为键,并将原始字符串添加为目标。要查找,您只需查找哈希键并查看返回的值。瞬间接近。但是,由于具有足够长的原始字符串,因此不会对其进行预先计算,因此在彩虹表中不会有任何影响。如果我知道您使用的盐和哈希算法,我仍然可以进行自己的字典攻击或蛮力攻击,但是突然之间,我需要依次尝试每次猜测,直到我很幸运为止,因此,如果您的密码正确,我不会在“合理的时间”内找到它。
您提出的问题的准确答案
如果我使用随机盐,如何比较该密码是否正确?
您的验证过程需要确切知道或推导为哈希过程选择的确切盐值。盐可能是随机生成的,但是如果是这样,则需要记录使用的确切值。
答案 1 :(得分:1)
首先,您必须按用户名在数据库中添加盐,然后用发布的密码对其进行哈希处理,最后将其与数据库中存储的密码进行比较