让我们设置一个场景,一个数据库已经被转储并且所有的密码都被散列了。
您注意到一些用户似乎已经注册了两次并且具有相同的哈希值。你通过你的散列破解程序运行这些散列,但什么也没有出现,大概是因为它们是加盐的,而你没有盐。但是因为用户在 2 个帐户上具有相同的哈希值,所以盐不会涉及任何随机值,对吗?
如果该站点仍然存在漏洞,并且您能够创建自己的帐户并检索自己的哈希值,那么您是否能够在知道注册密码的情况下对 salt 进行逆向工程?
让我们设置一个场景,一个数据库已经被转储并且所有的密码都被散列了。
您注意到一些用户似乎已经注册了两次并且具有相同的哈希值。你通过你的散列破解程序运行这些散列,但什么也没有出现,大概是因为它们是加盐的,而你没有盐。但是因为用户在 2 个帐户上具有相同的哈希值,所以盐不会涉及任何随机值,对吗?
如果该站点仍然存在漏洞,并且您能够创建自己的帐户并检索自己的哈希值,那么您是否能够在知道注册密码的情况下对 salt 进行逆向工程?
不考虑冲突,具有相同哈希值的两个用户意味着他们都具有相同的密码、盐和胡椒。因此,这通常意味着两件事之一
该站点为所有用户使用固定盐:这将方案呈现为仅胡椒密码散列方案(“盐”在代码中)。通过暴力破解,并利用明文密码的知识,您可以找出所述“盐”的值。
当然,这可以通过注册您选择的另一个帐户并尝试暴力破解类似hash(password + X)的X值来完成,这是您想要找出的值,然后将输出与您在创建新帐户后提取的哈希值进行比较。
一个像使用硬编码盐(仅限胡椒)一样愚蠢的网站可能会使用 MD5 或 SHA-1 之类的东西,这将使您的蛮力攻击更快。
该站点使用来自用户的某些信息的非唯一盐:(用户名、电子邮件等),您可以通过蛮力找到这些信息。
由于您提取的数据库不包含任何盐,因此很可能是第 1 种情况。
注意:仅仅因为在彩虹表中没有发现重复的哈希,这并不意味着它是一个简单的密码。它可能是具有两个帐户的同一用户使用相同的强密码。
我将尽我所能解决手头的整个问题,因为您希望以安全的方式执行用户身份验证。
首先,如果某个特定的“salt”在代码中实现为一段不可变的文本,那么它就不是真正的salt,真正的salt是随机的,也应该存储在数据库表的对应列中,或者通过如果盐不暴露,另一种方法。它也可以从一段用户数据、生日(非常可怕的想法,因为很多人都有相同的生日,请谷歌生日攻击)或其他东西生成,但在技术上与伪随机盐相关(更少安全的)。其他用户已经提到了这些点,但没有人提到为什么盐应该是随机的,而且这里也普遍缺乏关于如何作为一个整体执行身份验证的信息。
没有提到它应该实施的方式。对于严格的密码身份验证,应该使用安全的随机数生成器来创建至少与密钥空间大小相同的盐(我不知道是否存在用于生成大于该值的盐的用途,并且可能不会工作取决于实现,或者在其他方面可能更好,它将取决于实现)。
无论如何,只要选择保持不变,除非存在重新计算的方法,否则盐可以附加或前置(尽管通常在实践中是前置的)。如果您要以任何其他方式执行此操作,则需要存在另一个变量数据段来描述字符串或字符序列更改是如何发生的,除非您有一个可重复的序列,例如字节的交错,这将是看起来很奇怪,而且不一定更安全,因为暴力攻击将在密钥空间本身上进行。此外,在许多实现中,如果更改了如何应用盐的选择,则所有用户都需要创建一个新密码(事实上,考虑到散列,我不确定是否存在任何可以随意更改盐的应用的方法是单向的)。无论如何,
有趣的一点是,即使是 32 字节的随机信息,乍一看,它也不清楚如何通过盐来反转密钥空间的“屏蔽”。它必须纯粹以逐字节为基础完成,因为随机字节数据并不总是与人类可读的 ASCII 或 Unicode 字符匹配,即使在 Unicode 中也有些不可读,并且许多使用超过一个字节,所以如果我们逐字节处理问题,Unicode 将毫无用处。从快速概率的角度来看:如果盐是未知的,这大约是 2^256 * 2^256 * 2 种可能性(~2.68^154,超出了 googol 的一半,超过了百亿),不知道盐也不知道无论是附加还是附加而不了解实施细节。如果盐是已知的,那么我们'
这是关于我们遇到关键冲突可能性的地方。从本质上讲,它可能的多个值可以映射到同一个东西,而前两个数字是如此难以理解,以至于在第一次开始时找到一个映射到键空间内 2^256 个可能性的值会更快,换句话说,暴力破解密钥空间内的所有可能性,但盐渍化改变了一切。给定一个随机盐,一段明文以不同的方式映射到密钥空间。盐很重要。为了蛮力,我们可以迭代每个可能的值,执行猜测和测试方法,同时改变盐的应用方式,但前提是我们知道盐。否则它没有用,除非我们知道实现,或者如何攻击 SHA-256 算法本身。添加盐会以一种有价值的方式改变参数。我们只需要找到一些关键,当应用盐时会产生哈希本身,它应该映射到 2^256 种可能性,并且只要我们保持一致,我们如何应用盐就很重要。但是为了有用地考虑它,无论我们是在看大海捞针的顶部还是底部,salt 应用程序都会发生变化。
因此,在 SHA-256 实现中,最快的方法应该是测试每个可能的值,除非存在另一个漏洞,例如发现可计算的盐。对于 SHA-256,理论上这需要比地球年龄更长的时间来逆转(大约 10^65 秒,假设您每秒可以执行 10^12 或约 10 万亿次哈希),但随着更强大的硬件变得越来越强大,该指标正在减少可用的。如果盐可以很容易地被计算机使用,那么它只不过是字典攻击,除非实现细节很奇怪。转向计算能力,比特币网络的总哈希能力约为每秒 163 万亿次哈希,以比特币的概念为对数尺度,高于该数字,但远低于破解 SHA-256 所需的能力。整个比特币网络本身正在缩小差距,即使它仍然需要数千年,比地球的存在时间还要长,并且比已知宇宙的预期寿命还要长(假设我们处于宇宙寿命的中点附近)。显然,如果已知网络中这种疯狂的散列能力继续增长,则应该使用不同的密码存储技术。不过,目前尚未证明需要它。但是,由于这篇文章严格来说是关于散列和加盐的,所以我会继续,然后在最后讨论一些更好的方法。如果已知网络中这种疯狂的散列能力继续增长,则应使用不同的密码存储技术。不过,目前尚未证明需要它。但是,由于这篇文章严格来说是关于散列和加盐的,所以我会继续,然后在最后讨论一些更好的方法。如果已知网络中这种疯狂的散列能力继续增长,则应使用不同的密码存储技术。不过,目前尚未证明需要它。但是,由于这篇文章严格来说是关于散列和加盐的,所以我会继续,然后在最后讨论一些更好的方法。
通常破坏哈希的方式是通过盐(如果可以预先计算,比如像我这样的白痴程序员使用盐的静态值)。在随机加盐的情况下,您可以防止像 hashcat 这样的实用程序使用彩虹表(一种已知的预计算方法)成功,因为每个用户都应该有自己的随机加盐,即使是具有相同用户名和密码的用户应该有一个唯一的哈希和盐(理论上,除非在安全数字生成器、算法本身或在创建哈希的特定实例中发生“重击”)。话虽如此,在庞大的用户群中,多个用户仍可能拥有相同的哈希值是可能的。在这种情况下,如果电子邮件能够以某种方式映射到完整的 32 字节密钥空间,则它几乎更好,但我们可以' t 保证所有电子邮件至少为 32 字节,并且它不能防止恶意攻击者尝试将电子邮件作为盐(或任何基于 ASCII 的东西)。我想这里所需的“随机性”数量留给业务需求。
然而,按照这种方法,我们遇到了一种通过晦涩难懂的方法来实现的安全性,考虑到没有什么能阻止黑客假设这些知识,任何基于数学的东西都应该更好。如果盐不是要暴露的,它应该在内部保持在防火墙后面,其中需要 Web 应用程序向内部发送已知请求,并使用某种网络或传输层安全措施来防止窥探。一种可行的方法是应用程序提供一个唯一的用户 ID 并接收一个盐作为回报。如果是这种情况,Web 应用程序本身也需要加强,以防止窥探实施。
当攻击者没有内部访问权限时,这个先前的概念可以防止直接的 SQL 注入攻击。任何人发现自己获得了对内部网络的访问权,如果他们能够弄清楚如何操作文件系统、文件加密或访问该数据所需的证书,那么他们将变得毫无用处,尽管这很难做到这一点,因为它依赖于操纵整个子系统(绕过防火墙和任何 IDS/IPS,更不用说可能在防火墙的任一端点上发生的日志记录)。在这种情况下,可能会捕获活动并采取措施,但同时可能依赖于可能不是给定的人为干预。
因此,继续讨论 SHA-256 甚至 SHA-512 可能不安全的事实(尽管尚无证据),但它们也可能与 2FA 或 MFA 一起使用,很好,我稍后会谈到。另一个安全级别是适当的系统管理和安全设备。当今密码安全的常见实现是 PBKDF2、Bcrypt 和 Scrypt,它们允许添加密钥拉伸,从而为散列算法增加了另一层安全性。密钥拉伸本质上只是采用一个潜在的弱密钥并针对暴力破解方法对其进行加强。唯一需要注意的真正重要的事情是,如果密码已经足够长,则密钥拉伸最终可能会生成较短的较弱密钥,具体取决于实现。它还增加了从明文计算哈希的额外开销,
如果您正在创建一个非关键应用程序,其中漏洞是某种小 bean 并且不会暴露关键用户数据,那么不要再犹豫了。否则,如果您对更安全的东西感兴趣,请继续阅读。
目前,除了密码安全之外,唯一更好的方法是 2FA 或 MFA,它们不一定会增加太多的计算负担,更能真正识别用户。这些方法背后的这些想法假设密码在任何形式上都是固有的弱点,散列、加盐、胡椒等等,并表明证明身份的方式不太容易被操纵。这些方法要求用户呈现不同的事物以进行身份验证,即实现这些概念中的两个或多个:您拥有的东西、您知道的东西、您在的东西、您所在的某个地方或您所做的某事。如果遵循所有这些信息,则系统应该是安全的,除非子系统本身存在漏洞并且存在已知漏洞或零日漏洞利用。同时,它' 实现所有这 5 个概念以减少用户进行身份验证的负担是荒谬的。安全性有一个很好的平衡,它完全取决于组织的需要。