我的理解是盐不是秘密的,它只是意图与任何集中标准不同,因此你不能开发彩虹表或类似的攻击来打破使用该算法的所有哈希值,因为盐打破了彩虹桌。我在这里的理解可能不完全正确,所以如果我错了,请纠正我。
在一个广泛使用的开源软件中,盐会广为人知,这会让你受到攻击,因为现在他们可以简单地攻击你的哈希的盐渍版本并创建包含盐数据的彩虹表
正如我所看到的,有两种方法可以解决这个问题。第一种是在软件的每个新版本中更改盐,但这并不好,因为该软件的新版本将无法再针对旧密码哈希进行测试。
我想到的第二个解决方案是存储每个密码的盐;换句话说,每个密码都有不同的盐。缺点是盐必须以某种方式与密码哈希相关联,可能只是将它们紧紧地放在数据库中的密码旁边。甚至可以使用用户名(但可能不会,用户名可能太短)。
我的问题是,这可以接受吗?直接使用哈希密码存储盐有任何额外的风险吗?在我看来,在源代码中存储salt没有什么不同,因此通过使用密码存储salt不会造成安全性损失。
免责声明:我没有将它用于任何现实生活中的安全系统。事实上,我从未设计过任何类型的密码系统。我只是对自己的安全问题进行了模糊的教育。
答案 0 :(得分:19)
更新:使用称职的资料库,例如: Python的passlib。
这些用于生成每密码盐并且它们使用适当的散列算法(它不足以仅使用加密散列,例如SHA1;您必须以使其反转速度非常慢的方式应用它循环1000次或更多次等等。这就是密码哈希函数如bcrypt的工作方式。密码存储库可以正常完成所有这些;它们通常会生成一个分隔的字符串,以便它们可以确定使用的哈希系统和工作因子;你只需存储字符串而无需知道这一点。
您可以将盐存储在表格中的“纯文本”中。
盐无需保密即可生效
它只需要是随机的。
salt通过使散列值与相同或其他数据库中的相同密码无法比较来强化密码,并使大型预生成的常用密码列表无效到散列查找(例如'彩虹表')。
因此,每个用户的盐是唯一的并且随密码存储的随机值是至关重要的;问题中概述的替代方案(使用用户名作为salt,使用整个应用程序的单个salt值)每个都失败:
如果系统使用用户名或其他琐事,则可以将密码与其他系统中具有相同名称的其他用户进行比较(想象“管理员”或“root”用户帐户使用该密码的频率密码在不同的系统中......)
如果系统对同一系统中的所有用户使用单个随机盐,那么偶然拥有相同密码的两个用户将具有相同的哈希值,并且猜测一个用户的密码将轻而易举地损害另一个用户。< / p>
答案 1 :(得分:9)
试图保持盐的秘密是毫无意义的,因为盐渍和散列密码的整个实践只是因为我们从经验中知道我们甚至无法保证我们的数据库完全可靠。您最多可以单独存储盐,并希望攻击者能够访问您的数据库找不到它,但如果您使用了良好的哈希算法和足够长的单个盐,那么无论如何都应该是安全的。
盐的唯一目的是确保您无法在整个数据库甚至多个数据库中分摊暴力攻击的成本。
首先是改变盐 每个新版本的软件,但 这是不好的,因为新版本 该软件将不再是 能够测试旧密码 散列。
我看到的一个变体就是在安装过程中生成一个随机盐(当然还要跨版本保存),这样每个运行的实例都有不同的版本。当然,为每个密码设置不同的盐(可能除上述之外)还是更好。
答案 2 :(得分:1)
根据定义,salt必须是随机的才能有效。不要为此使用任何确定性值。这当然意味着您需要将其与散列密码一起存储在数据库中。 UNIX systems传统上甚至将哈希存储在与密码相同的字段中(salt是密码的固定长度前缀)。在数据库中,您可以在users表中添加其他列。
答案 3 :(得分:0)
为每个密码生成一个唯一的盐是完全正常的。盐可以是现有材料(例如UserID等)的产品或随机生成的。优点是随着盐的强度增加,对加密信息的攻击变得更加“不可行”。
请记住:每个加密算法都是易碎的。如果破解保护(通过彩虹表或其他方式)比信息价值更高,则信息可能只被视为“安全”。
编辑:
假设您对密码学非常陌生,这里还有一些提示:
答案 4 :(得分:0)
您的第二个解决方案“每个密码存储一个盐”是正确的,通常使用。
“Salt”主要是为了让两个用户拥有相同密码时难以检测到 - 因此您将已知的“Salt”混合到密码中。盐需要在密码检查时获得。
通常要么生成随机盐并使用密码存储它,要么使用其他标识符(用户ID,用户名等)作为盐。
答案 5 :(得分:0)
对数据库中的所有密码使用单个盐是有帮助的,但 比为每个用户提供唯一的盐更不安全。
基本上:较长(以字节为单位)的密码+盐会增加搜索空间,从而使得使用“库存标准”彩虹表更加困难。
但是,如果对所有条目使用相同的salt,则可以创建彩虹表专门来攻击您的软件。如果您的用户群很大,那么有人可能决定制作这样的彩虹表。
例如,如果您只是在散列之前在每个密码的末尾添加“和大量的盐”,攻击者可以构造一个由大量字符串生成的哈希值表,所有这些字符串以“和很多”结尾盐“。
出于这个原因,每用户盐是最好的方法。但是,请记住,您还希望密码+ salt为“long”。
如果你想使用主键,最好采用主键的 hash 而不是使用主键本身,因为如果用户43的密码+ salt看起来比如“myPassword00000000043”,攻击者可以建立一个表,假设中间有很多零。创建时间戳和随机字符串可能是更好的选择,因为PKeys有时可以很容易地找到或猜到。
注意:我不是真正的加密专家,不要在真实系统中使用此建议。
答案 6 :(得分:-1)
实际上你已经在用户表中存储了一个salt值:表的pkey。
您不必发明用于存储盐的新列。只需使用pkey。这个想法当然假定你有一个与用户名相关的pkey。例如用户名不是表中的pkey。
这是一个接近dup wtb:Password hashing, salt and storage of hashed values