8

我在 Google 上进行了全面搜索,但找不到使用Cryptsharp库的 Scrypt 用法(用于散列密码)的代码示例。

你能提供一个散列密码的样本吗?

4

2 回答 2

16

这只是一个调用,所以我将引导您完成参数:

  1. key:这是您的密码,使用 UTF-8 编码(不带字节顺序标记)将您的密码编码为字节数组;
  2. salt: 与 scrypt 函数的结果一起存储的一串安全随机字节,16 个字节应该足够了;
  3. cost:给定的建议是 262144,但如果您的服务器可以处理额外的负载,您可能希望增加该值;
  4. blockSize:看成本,给出的建议是8;
  5. parallel:除非您想尝试多线程,否则我会将其保持为 1;
  6. maxThreads: 一般来说null会做得很好;
  7. derivedKeyLength:嗯,这取决于,因为密码 128 应该足够了,但您的密码不太可能具有超过 128 位的安全性。

您应该至少存储盐和结果。如果要将它们存储为字符串,则可能需要使用 base 64 编码。

我建议您存储一条额外的数据:基于密码的密钥派生方案 (PBKDF) 的一个版本。比如说,将其设置1为使用 scrypt,使用给定的密钥编码、盐大小、成本、块大小等。在这种情况下,您可以稍后升级您的方案(您需要用户提供他/她的密码来执行此操作,所以您必须在线执行此操作,因此您最终将有多个计划同时运行)。

请注意,您可以链接 PBKDF 函数调用,因此您可以使用原始 PBKDF 输出并将其用作下一个 PBKDF 的输入。在这种情况下,用户不必提供密码(此提示来自 CodesInChaos 的另一个问题)。

于 2013-11-18T20:25:51.547 回答
4

@MaartebBodewes 通过非常明智的附加提示提供了一个很好的答案。这是一个包含他的建议的代码示例。我还建议阅读“你的密码太短了”,这表明了使用现代密码学的重要性,例如(在撰写本文时)BCrypt 或Scrypt

public string Hash(string secret, string salt)
{
    var keyBytes = Encoding.UTF8.GetBytes(secret);
    var saltBytes = Encoding.UTF8.GetBytes(salt);
    var cost = 262144;
    var blockSize = 8;
    var parallel = 1;
    var maxThreads = (int?)null;
    var derivedKeyLength = 128;

    var bytes = SCrypt.ComputeDerivedKey(keyBytes, saltBytes, cost, blockSize, parallel, maxThreads, derivedKeyLength);
    return Convert.ToBase64String(bytes);
}
于 2016-01-12T08:54:45.900 回答