C# Scrypt和Cryptsharp的示例代码

C# Scrypt和Cryptsharp的示例代码,c#,encryption,cryptography,scrypt,C#,Encryption,Cryptography,Scrypt,我在Google上搜索了所有地方,但我找不到使用该库的Scrypt用法(用于散列密码)的代码示例 您能提供一个密码哈希的示例吗?我将带您了解以下参数: 键:这是您的密码,使用UTF-8编码(无字节顺序标记)将您的密码编码到字节数组中 salt:与scrypt函数的结果一起存储的安全随机字节字符串,16个字节足够 成本:给出的建议是262144,但如果您的服务器能够处理额外的负载,您可能希望增加该值 blockSize:参见成本,给出的建议是8 parallel:除非您想尝试多线程,否则我会将此值

我在Google上搜索了所有地方,但我找不到使用该库的Scrypt用法(用于散列密码)的代码示例

您能提供一个密码哈希的示例吗?

我将带您了解以下参数:

  • :这是您的密码,使用UTF-8编码(无字节顺序标记)将您的密码编码到字节数组中
  • salt
    :与scrypt函数的结果一起存储的安全随机字节字符串,16个字节足够
  • 成本
    :给出的建议是262144,但如果您的服务器能够处理额外的负载,您可能希望增加该值
  • blockSize
    :参见成本,给出的建议是8
  • parallel
    :除非您想尝试多线程,否则我会将此值保持为1
  • maxThreads
    :通常
    null
    会做得很好
  • derivedKeyLength
    :这取决于密码的大小,虽然128位密码应该足够了,但密码的安全性不太可能超过128位
  • 你应该至少储存盐和盐。如果要将它们存储为字符串,可能需要使用base 64编码

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


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

    @Maartebodewes提供了一个极好的答案和非常明智的附加提示。下面是一个代码示例和他的建议。我还建议阅读“”一文,它显示了使用现代密码学的重要性,如(在撰写本文时)BCrypt或


    通常,如果有多个用户,您只需要多线程的性能优势。但是,如果您有多个用户,他们可能会为您执行多线程。因此,从这个意义上讲,它只有在您希望对使用高
    成本
    块大小
    的用户具有更短的延迟时才有用。它似乎工作正常,但我不能使用Crypter.CheckPassword()命令。是否可以将提供的密码与存储在用户记录中的salt进行散列,并将其与保存的密码进行比较?成本如何影响生成散列所需的时间?i、 e.如果我将262144的成本减半,它会花费一半的时间,还是线性度会比这低?是的,比较应该可以。最好使用以恒定时间返回的比较(攻击者不可能看到哪个字节失败,即使之前对密码进行了哈希处理)。成本是一个简单的for/next的输入,所以是的,这应该是一个lineair值(注意它应该是2的幂)。检查相对较小的部分以了解更多信息,它应该很容易阅读。@MaartenBodewes“安全随机字节的随机集”是什么意思?“与结果一起存储”的意思是:将此方法的结果以及作为参数传递给它的salt值分别存储在该用户的数据库行中的“key”和“salt”列中?William,有很多问题您尚未接受答案。你能看一下哪些可以接受吗?如果答案不完整,请让我们知道!只是需要一些时间来确认它是否有效,现在它已被标记为答案。您在这里使用的是哪个库?我没有看到任何关于Scrypt的
    Scrypt.ComputeDerivedKey()
    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);
    }