想象一下,我正在使用随机的、足够长的盐、使用密钥拉伸和安全散列对用户的密码进行散列。最后用对称密钥加密散列会更安全吗?
用加密保护散列密码有用吗?
威胁模型是什么?使用应用程序端的机密来保护密码存储可能是有益的,但前提是您认为这是您的数据库将受到威胁的现实场景——而您的应用程序服务器(持有该机密)也没有受到威胁。
通常,应用程序层被认为是更易受攻击的部分,而数据库层受到更多保护,因此使用应用程序端机密来保护数据被认为没有用。但这可能不是每个应用程序的情况,考虑到 SQL 注入的普遍性,我个人会对这个假设提出一些质疑。
引入应用程序端密钥的缺点是您现在必须担心密钥管理过程。如果密钥被泄露,您更换密钥的机制是什么?你会理所当然地旋转它吗?您的密钥是如何存储的,以便您可以移动服务器而不会丢失它(可能会使您的所有数据变得无用)?对于短期密钥(例如用于签署会话令牌),您可能不在乎,但对于长期密码存储,它变得很重要。
对称密码(尤其是分组密码)的另一个缺点是正确实施它们。由于您正在散列并且不需要可恢复性,因此您可以在散列中包含秘密(作为“胡椒”)......但是您将无法在密钥更改时重新散列所有密码数据,所以你必须有一个多键的翻转方法。
ETA 重新评论@Pacerier:
散列不能防止获得密码数据库的人进行离线猜测攻击。它只会增加攻击产生结果所需的时间;使用适当难度的散列方案(即密钥派生轮次而不是原盐长度本身),它有望将时间量增加到足够长的时间,让您注意到您已被黑客入侵并在太多之前更改每个人的密码他们的帐户丢失了。
使用密钥保护内容(使用加密或在散列材料中包含密钥)确实可以防止离线猜测攻击,但前提是密钥本身没有泄露。如果密钥位于与数据库服务器不同的应用服务器上,则只有在两台机器都受到攻击时密码才可攻击。
考虑到多种攻击可能最终同时损害两者,特别是如果应用程序服务器和数据库服务器是同一台机器,那么有多少好处是值得商榷的。正如所讨论的,在可管理性方面也需要付出代价。所以是否有净收益需要根据威胁模型具体情况进行判断。
作为纵深防御策略的一部分,我非常喜欢在安全系统之上添加保护层。但是,在这种特殊情况下,对这项任务使用对称加密会在系统中产生另一个问题。您必须负责密钥管理。密钥必须存储在某个地方,如果您的应用程序可以访问它,那么入侵您系统的攻击者很可能可以访问该密钥。
这样的过程给系统增加了额外的复杂性。复杂性是安全的敌人之一。我强烈建议不要这样做。
加密密码哈希可以在非常特殊的情况下保护密码。
在某些情况下,攻击者获得对您的数据库的读取访问权限,SQL 注入是一种可能性,泄漏的备份或处置的服务器是另一种可能性。在这种情况下,他可以暴力破解密码哈希。使用适当的哈希算法(密钥派生函数),强密码将是安全的,但弱密码可以通过字典攻击或多或少地快速检索(尝试 1000 个最常用的密码......)。
通过加密您的密码哈希,您可以在哈希中添加一个服务器端密码。这意味着,除了数据库之外,攻击者现在还需要服务器上的特权(以获取密钥)。这与胡椒可以给您带来的优势相同,但它的优势在于您可以在必要时交换密钥。
密钥是否安全存储并不重要,重要的是攻击者需要的额外权限。在最坏的情况下,攻击者将获得密码哈希,而您的情况与没有加密相同。
我认为有一个加密安全摘要的案例。
似乎普遍接受的是,今天的最佳实践是使用 bcrypt、PBKDF2 或类似算法来加盐,并将工作因素应用于密码摘要的生成。无论使用何种算法/工作因素,使用辣椒也是一种很好的方法,可以减轻不良或众所周知的密码容易被暴力破解。
但是,使用慢速算法需要随着硬件性能的提高而更新工作因子,并且必须选择它来减轻暴力攻击,但不要让登录系统的用户密码验证速度过慢。通过使用密码散列的对称加密,不再需要工作量和胡椒要求。如果对称密钥得到很好的保护(例如使用 HSM)并且已经建立了良好的密钥管理流程,我看不出这种方法有什么缺点。无论密码质量好坏,蛮力攻击的难度与暴力破解密钥相同。
我当然不会创建基础架构来执行此操作,因为之前关于密钥管理和将密钥与应用程序服务器分开的所有评论都适用。但是,如果基础设施已经到位并且建立良好,那么加密加盐密码哈希肯定有一些好处。