C# 使用HMACSHA1算法的哈希密码的最大长度是多少

C# 使用HMACSHA1算法的哈希密码的最大长度是多少,c#,encryption,.net-core,password-encryption,password-hash,C#,Encryption,.net Core,Password Encryption,Password Hash,我想在将密码存储到数据库之前对其进行哈希运算。有很多关于如何散列密码的示例,下面的C#代码依赖于HMACSHA1算法: public static void Main(string[] args) { Console.Write("Enter a password: "); string password = Console.ReadLine(); // generate a 128-bit salt using a secure PRNG

我想在将密码存储到数据库之前对其进行哈希运算。有很多关于如何散列密码的示例,下面的C#代码依赖于HMACSHA1算法:

public static void Main(string[] args)
{
    Console.Write("Enter a password: ");
    string password = Console.ReadLine();

    // generate a 128-bit salt using a secure PRNG
    byte[] salt = new byte[128 / 8];
    using (var rng = RandomNumberGenerator.Create())
    {
        rng.GetBytes(salt);
    }
    Console.WriteLine($"Salt: {Convert.ToBase64String(salt)}");

    // derive a 256-bit subkey (use HMACSHA1 with 10,000 iterations)
    string hashed = Convert.ToBase64String(KeyDerivation.Pbkdf2(
        password: password,
        salt: salt,
        prf: KeyDerivationPrf.HMACSHA1,
        iterationCount: 10000,
        numBytesRequested: 256 / 8));
    Console.WriteLine($"Hashed: {hashed}");
}
我想知道是否有一种方法可以根据密码的长度来确定密码哈希的长度。因此,如果用户有一个长度为x的密码,有没有办法计算散列的长度

我想知道它,因为在我的数据库中,密码列当前是一个包含128个字符的varchar。在此基础上构建的RESTAPI应该限制密码长度,这样数据库就不会因为密码太长而崩溃,并生成超过128个字符的密码哈希

或者说数据库列是256个字符的varchar,API只允许小于或等于30个字符的密码,这样就永远不会达到限制,这是最好的做法吗


如果答案独立于代码语言,那就好了,这更像是一个一般性的问题。

可以指定PBKDF2的输出。PBKDF是一种基于密码的密钥派生函数。通常,它们有一个键扩展阶段,允许指定输出

然而,如果PBKDF2用作密码散列而不是密钥派生,则保持配置的散列的大小;这提供了可以从算法中检索到的最大安全性。在这种情况下,SHA-1生成160位/20字节

除非您确实需要文本,否则输出可以存储为20字节的静态二进制文件。在您的情况下,应该将其存储为20字节的base64版本。这相当于一个固定的28字节:
((20+2)/3)*4=28
来计算基64扩展。但是,您的代码明确指定输出大小为
256/8=64
字节。快速计算表明,该大小始终使用88个以64为基数的字符

使用SHA-1时生成64个字节不是一个好的设置,因为它需要PBKDF2的内部函数运行4次,这样就不会让您只运行一次就生成20个字节,从而给攻击者带来好处。毕竟,攻击者只需检查前20个字节以确保密码匹配,并且只需要四次运行中的一次。PBKDF2用于将密钥大小扩展到散列大小的方法效率很低,可能被认为是设计缺陷

另一方面,10.000次迭代不是很高。对于PBKDF2,您应该:

  • 将基础哈希的输出大小指定为输出大小(SHA-1为20字节,而不是64字节),然后
  • 使用更多的迭代次数(受您在PBKDF2中可以花费的CPU时间限制)
  • 密码的大小对密码哈希的大小没有任何影响



    请注意,其他运行时上的一些密码哈希本身会创建一个密码哈希字符串,与Unix系统上的
    crypt
    更兼容。因此,它们会有更大的输出,而不是直接兼容。

    一般来说,哈希输出的大小是由算法固定的,不取决于哈希的数据量。谢谢您的回复。对不起,你说的
    只生成散列的输出大小是什么意思?
    ?我想这在上下文中是很清楚的,但我很快就修改了它