动态生成的非随机盐的加密安全

信息安全 密码学 密码 哈希 随机的
2021-08-20 12:01:51

因此,当谈到安全性时,当我有一个看起来不错的想法,但似乎没有其他人在做时,我会尝试假设我忽略了一些明显或其他重要的事情。这是一个这样的案例...

这个问题的背景是我开始研究的身份验证系统。我过去曾实现过类似的系统,并且通常都围绕“盐和哈希”的事情,但我绝不是密码安全方面的专家。

由于我正在为我的用户记录中的 16 个随机字节的盐定义存储的过程中,我突然想到,如果有人窃取或以其他方式访问了我的用户数据,可能有一种方法可以减少攻击面。我的操作基于以下假设:

  1. 如果黑客窃取了我的用户数据,他们可以访问用户密码的加盐 +(重复)散列表示,以及加盐值本身。
  2. 如果黑客想要确定该密码的纯文本值,他们面前有一些蛮力劳动。
  3. 但是,由于加了盐,该蛮力攻击的搜索空间大大减少了。*

*我不是 100% 确定第三点是正确的,但对我来说,如果一个蛮力算法可以假设预哈希值由<8-or-so-bytes-of-password> + <16-bytes-from-stolen-salt>(或密码和盐值的类似组合)组成,那么我们'已经通过算法上显着的数量减少了搜索空间。

<这里的问题长度的强制性中间问题道歉>

因此,以上是我目前的思路,我正在考虑的解决方案基本上归结为使用关于用户的已知常量值来动态生成盐以在散列步骤期间使用。

鉴于盐值实际上不需要是加密的“任何东西”,只要它们无法猜测到需要暴力发现的程度,基本上对提供的用户名和密码进行一些转换就足够了(例如,应用一些 SHA-2 优点和专有密码),并在散列步骤中使用它?

当然,如果有人也窃取了代码,那么“秘密”盐生成是毫无意义的。 我试图实现的唯一增加的安全性是强迫黑客窃取我的数据我的代码,如果他们想要上面第 3 点中描述的减少搜索空间的便利。

我希望我已经充分(而不是过于冗长)描述了我的问题和推理。我希望回答的具体问题是,这是否是一种存储和比较用户密码的加密(或其他)安全方法。


编辑:看来我的问题的关键点可能已经在上面的噪音中迷失了。让我试着更明确一点:

  1. 访问用于生成散列值的盐是否有助于对发现实际密码的暴力攻击?
  2. 如果是这样,那么除了数据本身之外,还要让黑客不得不窃取我的代码是否有意义?
  3. 动态生成盐的一般方法(使用可重现、非随机但不可猜测的方法)是否不明智?
3个回答

您对盐的作用有些误解。并不意味着“攻击者无法猜测”。如果它是不可猜测的,那将是一段机密数据,我们称之为“钥匙”,而不是“盐”。

盐的存在是为了使密码派生过程独一无二,以防止攻击者在攻击多个密码时获得规模经济。如果攻击者试图猜测三个密码,他所付出的代价必须是攻击一个密码的三倍。“规模经济”的一个大例子是一个大表,其中包含常用密码的预计算哈希(或其邪恶的后代,彩虹表,它只是一个巨大的预计算表,并有一个技巧来保持它只是巨大的)。在存在盐的情况下,没有一个哈希函数,而是每个盐值一个; 或者,换句话说,预先计算的表将特定于给定的盐(计算期间使用的盐),并且对于攻击任何不使用该盐的密码毫无价值。

当然,如果攻击者可以获得哈希密码的副本,但无法获得相应的盐,他的任务确实变得非常困难。但这不是一个合理的场景:如果您有一个存储区域,可以将盐放在攻击者无法触及的地方,那么您为什么不将散列密码也存储在那里呢?所以安全分析假设攻击者知道盐。它们的有用性源于它们的独特性:在相同或不同的系统上,在相同或不同的时间,没有两个不同的散列密码具有相同的盐值(即使是同一用户的两个连续密码:当您更改密码时,您还要换盐)。

您可以以任何您认为合适的方式生成和存储盐,即使使用“动态生成器”,只要重复使用盐值的可能性可以忽略不计。这正是因为它们应该是公开的,并且攻击者不必“无法猜测”——无法猜测的事情需要重型火炮

有一个稍微相关的概念,有时被称为“pepper”:一个插入到散列过程中的密钥(参见前面问题)。该密钥在系统范围内共享。这个想法是唯一的密钥比整个哈希密码数据库更容易保密,至少在某些配置中(例如,您将其保存在私有配置文件中,而不是 SQL 数据库中)。“pepper”概念意味着更复杂的管理(要备份而不丢失或在前端服务器之间共享的另一件事),并且仅在攻击者可以转储用户数据库但不能转储用户数据库的边缘场景中才有价值。完整的主机系统。在任何情况下,“胡椒”都没有意识到盐提供的独特性,因此胡椒不能代替盐——只能补充盐。

评论有点长。

盐确实给了他们一个起点。

但是,这通常是一个没有实际意义的问题,因为知道特定密码的价值几乎总是只与他们可以从您的用户表中反转的密码总数有关。换句话说,如果他们不得不花费数年的计算机时间来提取 10 个密码,那么这些数据实际上没有任何价值。

从站点中提取用户名和密码只有价值,因为用户倾向于在多个服务中重复使用相同的密码。对于黑客来说,以用户身份登录他们从中提取密码的同一站点上的用户显然并不重要,因为如果他们能够从您那里获取密码,那么他们很可能也可以提取他们想要的任何其他数据。

在出售这些用户名和密码时,它们具有价值,因为这些密钥可以打开其他锁,例如 Facebook 帐户和银行网站。他们唯一有价值的其他情况是通过在公共论坛(ala Sony)上发布用户名/密码来公开羞辱您。

因此,如果您对每个密码使用随机盐,那么您已经将获得任何有价值的东西所需的时间增加到愚蠢的程度。此外,拥有在合理时间内破解所有这些密码所需资源的人很可能是政府机构……这是一个完全不同的问题。

这导致我投票:找到一个不同的问题来解决。

一条重要的安全法则是“停止尝试自己加密”。停止创建自己的身份验证系统,只使用标准系统。你的建议没有什么特别的问题,但在提出问题时,你表明你没有完全理解这个问题。这就像用扳手看着木匠用锤子敲钉子一样。与其说它不起作用,不如说是你不信任他的能力。

如果您想让黑客的生活更加艰难,请进行尽可能小的更改。

让我们简化您的问题:我能做些什么来让破解密码变得更难?强迫他们窃取源代码有帮助吗?

例如,使用 SHA-2 会使黑客更难。他们的工具针对 SHA-1 和 MD5 进行了优化,许多工具不适用于 SHA-2。

或者,如果您真的想要源代码中的秘密,那么您建议的复杂内容不会比简单地在盐值前面添加“x”更能改善这种情况。这样,黑客可以窃取盐和哈希值,但在不知道源代码的情况下无法对它们做很多事情。

请记住,有些程序员会追随您,并且必须维护您的代码。如果这是一些奇怪的系统,他们会沮丧地扯掉头发。如果是普通的认证系统,或者是一个小改动的普通系统,那他们就不会骂你的名字。