在c#中使用随机盐进行哈希处理?

时间:2016-06-10 06:42:43

标签: c# php hash salt

我使用我的.NET(C#)客户端中的CryptSharp Library使用随机生成的盐(Blowfish)来哈希用户的密码。

然后我继续将散列密码发送到我的远程服务器,并将其存储在MySQL数据库中。

当我尝试使用相同的纯文本密码登录时,发送的内容与数据库中存储的内容之间存在哈希不匹配。 (很可能是因为盐每次都在变化)

我不想向我的PHP端发送未加密的纯文本密码,如何在不使用静态盐的情况下实现此目的?

哈希(C#):

string passHash = Crypter.Blowfish.Crypt(Password.Text, Crypter.Blowfish.GenerateSalt());

我不想在注册时创建一个新列来存储客户端的盐,但如果我必须,我会这样做。

4 个答案:

答案 0 :(得分:0)

答案很简单,与使用的语言无关:

  1. 如果您希望服务器在数据库中存储散列密码,您可以使用任何散列函数存储它们(如果您想使暴力破坏需要更长时间,我建议使用SHA256或BCrypt。到BCrypt是盐,迭代次数直接存储在哈希中,因此数据库中不需要额外的列)。

  2. 如果您想加盐,您需要存储盐柱并将其传输到客户端以便在散列过程中使用。通常,您将为每个用户使用随机盐,并且只有在更改密码时才会更改。这是推荐但不是必需的 - 它使得彩虹表攻击变得毫无用处。

  3. 如果您担心通过网络传输,而不是特别关注数据库,您可以在身份验证期间在服务器上生成随机盐,并且只使用一次 - 但服务器需要用于比较的原始密码。

  4. 你也可以结合所有这些方法,虽然我不认为这是任何地方的标准做法。

答案 1 :(得分:0)

您可以使用:

*ngIf="project"

var result = string.Empty; using (var sha1 = new SHA1Managed()) { result = ToHex(sha1.ComputeHash(Encoding.ASCII.GetBytes(Password.Text))); } 看起来像这样:

ToHex

以前的代码在多次调用时确实产生相同的哈希,而不需要涉及盐。

.NET框架中还支持其他更安全的SHA算法版本,例如public static string ToHex(byte[] bytes) { return string.Concat(bytes.Select(b => b.ToString("X2"))); } 。使用SHA1或SHA256取决于您的安全要求。

答案 2 :(得分:0)

加密密码的目的是将密码安全地存储在数据库中。 CryptSharp不会帮助您确保通过电线传输。

您可以采取多种方法,但最简单的方法可能是通过SSL与服务器进行通信。如果您不想使用公共CA,请使用自签名证书并挂钩ServicePointManager.ServerCertificateValidationCallback以接受您自己的CA或证书。

答案 3 :(得分:0)

要将密码从客户端传输到服务器,需要加密的HTTPS / SSL连接。它会在将用户输入发送到客户端之前对其进行加密,因此ManInTheMiddle无法进行窃听。散列必须在服务器端完成,至少是散列的一部分。

CryptSharp支持通用存储格式,并在生成的哈希中包含salt。不幸的是,似乎没有一种验证方法,它会提取用过的盐,至少我找不到。

我可以推荐的另一个库是BCrypt.Net,盐也与哈希一起存储(不需要额外的字段),验证非常简单:BCrypt.Verify(password, stored_hash)