首页 文章

为哈希隐藏盐的必要性

提问于
浏览
95

在工作中,我们有两种相互竞争的盐理论 . 我工作的产品使用类似用户名或电话号码来加密哈希值 . 基本上每个用户都有不同的东西,但我们可以随时使用 . 另一个产品为每个用户随机生成一个salt,并在每次用户更改密码时更改 . 然后在数据库中加密盐 .

我的问题是,第二种方法是否真的有必要?从纯粹的理论角度来看,我可以理解它比第一种方法更安全,但从实用性的角度来看呢 . 现在要对用户进行身份验证,必须将salt解密并应用于登录信息 .

在考虑之后,我只是没有从这种方法中看到真正的安全性收益 . 将盐从帐户更改为帐户,即使攻击者知道如何快速确定每个帐户的内容,仍然会使某人尝试强制执行散列算法变得非常困难 . 这是基于密码足够强的假设 . (显然,找到一组密码的正确哈希值,它们都是两位数,比找到8位密码的正确哈希值要容易得多) . 我的逻辑是不正确的,还是我缺少的东西?

EDIT: 好的,所以这里's the reason why I think it'真的没有办法加密盐 . (lemme知道我是否在正确的轨道上) .

对于以下说明,我们假设密码总是8个字符,盐是5,所有密码都由小写字母组成(它只是使数学更容易) .

每个条目都有一个不同的盐意味着我不能使用相同的彩虹表(实际上,如果我有一个足够大小的技术,我可以,但暂时不要忽略它) . 根据我的理解,这是盐的真正关键,因为要破解每个帐户,我必须重新发明轮子,以便为每个人说话 . 现在,如果我知道如何将正确的盐应用于密码以生成哈希,我会这样做,因为盐实际上只是扩展了哈希短语的长度/复杂性 . 所以我会减少我需要生成的可能组合的数量以“知道”我有13 ^ 26到8 ^ 26的密码盐,因为我知道盐是什么 . 现在,这使它变得更容易,但仍然非常困难 .

所以加密盐 . 如果我知道盐是加密的,我不会先尝试解密(假设我知道它有足够的加密级别) . 我会忽略它 . 不要试图找出如何解密它,回到前面的例子,我只会生成一个更大的彩虹表,其中包含13 ^ 26的所有键 . 不知道盐肯定会减慢我的速度,但我认为这不会增加尝试首先破解盐加密的重大任务 . 这就是为什么我不认为这是值得的 . 思考?

这是一个链接,描述了在暴力攻击下密码的持续时间:http://www.lockdown.co.uk/?pg=combi

10 回答

  • 3

    这里的答案是问问自己你真正想要保护的是什么?如果有人可以访问您的数据库,那么他们可以访问加密的salt,并且他们也可以访问您的代码 . 他们可以解密加密盐吗?如果是这样,那么无论如何加密都是无用的 . 盐实际上是为了制作它所以如果它被打破,就不可能形成彩虹表来一次性破解你的整个密码数据库 . 从这个角度来看,只要每种盐都是独一无二的,就没有区别,你的盐或每个密码的加密盐都需要蛮力攻击 .

  • 3

    隐藏盐是不必要的 .

    每个哈希都应该使用不同的盐 . 实际上,通过从加密质量随机数生成器获取8个或更多字节很容易实现 .

    来自previous answer of mine

    Salt有助于阻止预先计算的字典攻击 . 假设攻击者有可能的密码列表 . 他可以散列每个并将其与受害者密码的哈希值进行比较,看看它是否匹配 . 如果列表很大,这可能需要很长时间 . 他不希望在下一个目标上花费那么多时间,因此他将结果记录在“字典”中,其中哈希指向其相应的输入 . 如果密码列表非常长,他可以使用像彩虹表这样的技术来节省一些空间 . 但是,假设他的下一个目标是他们的密码 . 即使攻击者知道盐是什么,他的预计算表也毫无 Value - 盐会改变每个密码产生的哈希值 . 他必须重新哈希他列表中的所有密码,将目标的盐粘贴到输入上 . 每种不同的盐都需要不同的字典,如果使用了足够的盐,攻击者就没有足够的空间来存储所有字典 . 交易空间以节省时间不再是一种选择;攻击者必须回退散列每个密码在他想要攻击的每个目标的列表中 . 因此,没有必要保持盐的秘密 . 确保攻击者没有与该特定盐相对应的预先计算的字典就足够了 .


    在考虑了这一点之后,我更好地假设盐不能被隐藏,并且设计系统尽管如此安全 . 我提供了更详细的解释in another answer.

  • 2

    我对“盐”的理解是它使得破解变得更加困难,但它并没有试图隐藏额外的数据 . 如果你试图通过使盐“秘密”来获得更多安全性,那么你真的只需要加密密钥中的更多位 .

  • 2

    第二种方法只是稍微安全一点 . Salts保护用户免受字典攻击和彩虹表攻击 . 它们使一个雄心勃勃的攻击者更难以破坏整个系统,但仍然容易受到针对系统中一个用户的攻击 . 如果你使用公开的信息,比如电话号码,攻击者就会意识到这一点,那么你就已经为他们的攻击做了一步 . 当然,如果攻击者获得您的整个数据库,盐和所有数据,那么问题就没有实际意义了 .

    EDIT: 在重新阅读了这个答案和一些评论之后,我发现有些混乱可能是因为我只是在比较问题中提出的两个非常具体的案例:随机盐与非 - 随机盐 . 如果攻击者获得你的整个数据库,那么使用电话号码作为盐的问题就没有实际意义了,根本就是使用盐的问题 .

  • 3

    隐藏的盐不再是盐 . 这是辣椒 . 它有它的用途 . 它与盐不同 .

    Pepper是添加到密码salt的密钥,它将哈希变为HMAC(基于哈希的消息认证码) . 能够访问哈希输出和盐的黑客理论上可以强制猜测将生成哈希的输入(因此在密码文本框中传递验证) . 通过添加胡椒,您可以以加密随机方式增加问题空间,在没有严重硬件的情况下使问题难以处理 .

    有关胡椒的更多信息,请查看here .

    另见hmac .

  • 1

    这是一个简单的例子,说明为什么每个哈希都有相同的盐是不好的

    请考虑下表

    UserId  UserName,   Password
         1  Fred       Hash1 =  Sha(Salt1+Password1)    
         2  Ted        Hash2 =  Sha(Salt2+Password2)
    

    Case 1 when salt 1 is the same as salt2 如果Hash2替换为Hash1,则用户2可以使用用户1密码登录

    Case 2 when salt 1 not the same salt2 如果Hash2被Hash1替换,则user2无法使用用户1密码登录 .

  • 41

    ...类似于用户名或电话号码来填充哈希值 . ......我的问题是第二种方法是否真的有必要?从纯粹的理论角度来看,我可以理解它比第一种方法更安全,但从实用性的角度来看呢?

    从实际的角度来看,salt是一个实现细节 . 如果您更改了用户信息的收集或维护方式 - 并且有时会更改用户名和电话号码,使用您的确切示例 - 那么您可能已经损害了您的安全性 . 您是否希望这种面向外部的变更有更深层次的安全问题?

    是否停止要求每个帐户都有一个电话号码需要进行完整的安全审查,以确保您没有打开这些帐户以达到安全妥协?

  • 92

    有两种技术,目标不同:

    • “salt”用于使两个相同的密码以不同方式加密 . 这样,入侵者就无法有效地对整个加密密码列表使用字典攻击 .

    • 在散列消息之前添加(共享)“秘密”,以便入侵者无法创建自己的消息并接受它们 .

  • 0

    我倾向于隐藏盐 . 我通过在对其进行散列之前将1到1024之间的随机数添加到密码的开头来使用10位盐 . 当比较用户输入的密码与哈希时,我从1循环到1024并尝试盐的每个可能值,直到找到匹配 . 这不到1/10秒 . 我有这样的想法,从PHP password_hashpassword_verify这样做 . 在我的例子中,"cost"对于10位盐是10 . 或者从另一个用户说的,隐藏"salt"被称为"pepper" . 盐未在数据库中加密 . 它快's brute forced out. It would make the rainbow table necessary to reverse the hash 1000 times larger. I use sha256 because it',但仍然被认为是安全的 .

  • -1

    实际上,这取决于您尝试保护数据的攻击类型 .

    每个密码的唯一salt的目的是防止对整个密码数据库的字典攻击 .

    加密每个密码的唯一盐会使破解个人密码变得更加困难,是的,但是你必须权衡是否真的有很多好处 . 如果攻击者通过蛮力发现此字符串:

    Marianne2ae85fb5d
    

    哈希到存储在数据库中的哈希值,真的很难弄清楚哪个部分是通道,哪个部分是盐?

相关问题