我们的要求是用独特的盐存储每个密码。
查看他们的旧代码,我看到它使用。
该文档说“填充了一系列字节,具有一个随机非零值的密码强的序列。”
并不是说盐是独一无二的。
我应该根据一天中的时间生成一些数据吗?也许是GUID?还是这些组合?
有什么建议吗?
Our requirement is to store each password with a unique salt.
Looking at their old code, I see it uses RNGCryptoServiceProvider.GetNonZeroBytes.
The documentation says that it "Fills an array of bytes with a cryptographically strong sequence of random nonzero values."
That does not say that the salt is unique, though, does it.
Should I generate some data based on the time of day? Maybe a GUID? Or a combination of these?
Any suggestions?
发布评论
评论(3)
使用评论中的建议,我将从此开始:
Using suggestions from the comments, I will start with this:
您想要32个字节独特的盐。为了保证的唯一性,您需要一个密码,而不是统计上的唯一性。由于密码是一对一的,因此,如果使用相同键加密唯一的输入,则将获得唯一的输出。因此,加密计数器0、1、2、3,...将为您提供独特的输出。
32个字节为256位。对于块密码来说,这很大,例如,AES为128位。您没有说您需要多少个独特的盐。如果您需要少于2^128盐,则只需使用一个AES块,并添加了16个字节。否则,您将需要两个AES块。这需要将AES输入扩展到256位,并带有领先的零,并期望与AES返回两个街区。
128位AES +随机伪代码:
256位AES伪代码:
You want a 32 byte unique salt. For guaranteed uniqueness, rather than statistically highly probably uniqueness, you need a cipher. Because ciphers are one-to-one, if you encrypt unique inputs with the same key then you will get unique outputs. Hence encrypting a counter 0, 1, 2, 3, ... will give you unique outputs.
32 bytes is 256 bits. That is large for a block cipher, AES is 128 bits for example. You do not say how many unique salts you need. If you need less than 2^128 salts, then you only need to use one AES block, with 16 bytes of random added. Otherwise you will need two AES blocks. That requires extending the AES input to 256 bits with leading zeros and expecting a two block return from AES.
128 bit AES + random pseudocode:
256 bit AES pseudocode:
适当的密码障碍库通常自己生成盐,并将其直接包含在哈希弦中,这是推荐的方法。一个很好的例子是bcrypt:
如果您需要单独生成盐,通常的方法是像您在示例中一样从OS的随机来源读取随机字节,或者如本示例所示dotnet文档。
对于每个密码,盐应该是唯一的,以防止可以将彩虹表用于多个密码。使用长时间的随机盐,机会极小很小,您获得了两次相同的盐。在最坏的情况下,攻击者可以使用彩虹表作为两个密码而不是一个密码,蛮力仍然会更快。
Appropriate password-hash libraries usually generate the salt on their own, and include it directly into the hash-string, this is the recommended approach. A good example is BCrypt: https://www.nuget.org/packages/BCrypt.Net-Next/
If you need to generate the salt on your own, the usual way is to read random bytes from the random source of the OS as you did in your example, or as is shown in this example from the DotNet documentation Rfc2898DeriveBytes.
The salt should be unique for each password, to prevent that a rainbow table can be used for more than one password. With a long random salt the chance is extremely small that you get the same salt twice. In the worst case, an attacker could use a rainbow table for two passwords instead of one, brute-forcing will still be faster.