我正在设计一个如下所示的身份验证系统:
WHERE `Password` = SHA1(CONCAT('$hashedPassword',`Salt`)) AND [..]
目前我的盐是64字节。这足以使字典攻击变得不可行吗?
我确定sha1已知漏洞,但它是我可以在数据库层上使用的我的MySQL(5.1)版本上唯一可用的函数,而不是通过应用程序和数据库之间的连接选择纯盐层
答案 0 :(得分:19)
我认为你误解了盐的概念。 Salts不会显着阻止或减缓词典和暴力攻击。
使用salt的重点是避免某人已经预先计算对您的密码哈希值进行字典/强力攻击(例如使用彩虹表)。因此,它只需要足够长就可以排除这种表已存在于特定盐的可能性。
考虑到这种彩虹表的典型大小,有些人已经预先计算了这样的表,即使是8字节左右的小尺寸盐也是如此(考虑可能的盐的数量:256^8 = 18446744073709551616
)。前提当然是盐是随机生成的,并且您不会多次使用相同的盐值。 64字节不会受到伤害,当然,这没有什么不妥。
但是,如果你想使蛮力或字典攻击变得不可行,那么使用更长的盐就无济于事了。相反,让您的用户选择强密码并考虑使用key stretching。
答案 1 :(得分:8)
我的Practical Cryptography(Ferguson,Schneier)副本的版权日期为2003,建议使用256位(32字节)的盐长度。它说128位“可能”还可以,但是,正如它指出的那样,位很便宜。鉴于此,对于每个密码,在磁盘上存储64字节的相对最小的成本似乎是合理的。这可能是矫枉过正,但不会受到伤害。
您可能还需要考虑password stretching(多次重复散列函数)以增加通过强力攻击密码的计算复杂性。添加几百毫秒来检查密码的成本会大大增加暴力攻击的成本。
答案 2 :(得分:4)
salt确定需要多少 space 来存储预先计算的表(例如Rainbow Table),该表允许攻击者快速查找给定哈希的密码。
哈希迭代次数(不是盐)决定攻击者在候选词典中尝试每个密码所需的时间。
每一点盐都会使查找表所需的空间翻倍。因此,8字节(64位)将导致1600万太字节的空间乘数 - 使总空间很好地进入yottabyte范围(并且可能超出大多数攻击者的范围)。
答案 3 :(得分:1)
salt用于向密码添加额外的随机位make certain attacks less efficient。所以盐添加的熵越多越好。
目前,PKCS #5建议盐长度至少为64位熵,通常建议bcrypt uses 128 bits,您甚至可以使用更多。但肯定有一点,你不会增加额外的实际复杂性,因为最终的复杂性已经是乌托邦。
因此,每个密码至少应有一个唯一的盐,这样一次只能破解一个密码。充其量,使用已经过验证的密码存储方案。
答案 4 :(得分:1)
图书:
密码工程:设计原则和实际应用
Niels Ferguson,Bruce Schneier和Tadayoshi Kohno21.2.1腌制和拉伸
由于位很便宜,为简单起见,我们建议使用256位盐。
答案 5 :(得分:0)
8个字节足够了。
当你在/ etc / shadow中查看用户密码的Linux(内核版本3.16)时,可以看到如下表格:
$ $ ID $盐encrypted_password
在我的Linux版本中,盐是8位数字,所以8字节,我认为内核开发人员知道他们做了什么,所以我也使用8字节为我的盐,它来自密码安全伪随机生成器源。在Linux中,您可以简单地读取/ dev / random(当熵低时阻止)或/ dev / urandom(不阻止)。
有关更多信息,请阅读crypt的联机帮助页。