沿着加密的 AES 密钥存储密码哈希的安全隐患

信息安全 密码学 加密 密钥管理
2021-08-26 19:42:06

我正在使用 PKCS#5 标准使用随机且唯一的盐和输入的用户密码生成密钥。将此密钥视为“加密”密钥。

“加密”密钥用于加密随机 AES 密钥。每个用户都有一个与其配置文件关联的 AES 密钥。

因此,用户的个人资料将包含以下信息:

  • 用于身份验证的密码哈希。
  • PKCS#5 算法中使用的盐。(从 PKCS#5 V2.0 文档中,我们知道此信息不需要保护)。
  • 加密的 AES 密钥随机生成,并使用 PKCS#5 算法生成的“加密”密钥以及盐和用户密码进行加密。

我在问自己同时拥有密码的哈希、盐和加密的 AES 密钥是否危险。我 99.9% 确信这不是问题,但它是否可以促进拥有所有这些细节的攻击者的工作?

3个回答

只是为了确保我得到它 - 你正在存储:

  • 散列密码 - 理论上无法恢复密码,因为散列是一种方式。

  • 盐 - 只是加密密钥方程的一半,因为您也需要明文密码,对吗?

  • 加密的 AES 密钥

所以...... AES 密钥是真正的回报,大概是因为它被用于加密通信或存储。

当您希望服务器使用密钥时,我猜过程是这样的:

  • 用户给系统他的密码
  • 系统检查密码,对其进行散列 - 这很好。
  • 系统获取密码(不是哈希!)和盐并计算加密密钥
  • 系统获取加密密钥并解密 AES 密钥

然后系统会适当地处理 AES 密钥,做它需要做的任何事情,并从内存中删除 AES 密钥的任何副本,这样它就不会在任何地方清晰可见。

照原样,我没有看到其中的弱点,但是您已将所有内容归结为密码的强度。如果攻击者应该获取您的数据存储,他需要但没有的一件事就是密码。如果用户有一个容易猜到的密码,那么攻击者将获得用户的 AES 密钥。

我想如果是分析这个系统,我不会太担心——相反,我会开始研究用户密码的通信方式以及解密后如何处理 AES 密钥——这些也是弱点并且可能比哈希、盐和加密密钥的后端数据存储更容易破解。

如果攻击者想要破坏您的系统,他会尝试猜测密码。这意味着尝试潜在的密码直到一个“匹配”(这就是所谓的字典攻击)。配什么?攻击者可以通过两种方式查看密码是否正确:

  1. 通过验证存储的哈希值;
  2. 通过应用 PKCS#5 密码推导(PBKDF1 或 PBKDF2,PKCS#5 描述两者),然后解密 AES 密钥,然后使用获得的密钥尝试解密使用密钥加密的任何内容,并查看结果是否有意义。

攻击者将采用对他来说最容易的任何方式。PBKDF* 函数包括一些使字典攻击更难的特性,即盐和可配置的内部迭代次数。迭代使每次密码试验变得昂贵。salt 可以防止攻击者使用预先计算的哈希表(例如“彩虹表”)来优化事物。PBKDF2 在这方面被认为相当出色(尽管bcrypt可以说更好)。如果您的密码验证散列不包含相同的功能,那么该散列攻击者将使用的弱点。

简而言之,您的安全性将是您的密码验证哈希和 PKCS#5 密钥派生中较弱的安全性。

更好的方案如下:

  • 根据用户密码,您可以使用适当的密钥导出函数(例如 PBKDF2 或 bcrypt)导出密钥K。这使用盐S
  • 你用K对称地加密你的“AES 密钥” ,产生一些值B
  • 您为每个用户存储h(K)SB (其中h是一个安全散列函数——我建议使用 SHA-256)。

要验证密码,您可以使用存储的盐S重新运行密钥派生函数,并对结果进行散列以查看它是否与存储的h(K)匹配。如果要解密B,只需使用重构的K这样,您可以确定用于加密的密钥派生和密码验证哈希同样能够抵抗字典攻击。

我认为您不想将哈希存储在 AES 密钥旁边。如果有人要访问原始加密的 AES 密钥、哈希和盐,他们可以很容易地从哈希中暴力破解密码。鉴于今天的计算能力,使用现成的 GPU 强制使用所有只有 6 个字母的字母数字密码需要 2 秒。像 MD5、SHA1 甚至 SHA256 这样的算法可以很容易地用今天的少量计算能力进行暴力破解。

http://www.zdnet.com/blog/hardware/cheap-gpus-are-rendering-strong-passwords-useless/13125

http://www.engadget.com/2010/08/16/gpus-democratize-brute-force-password-hacking/

http://www.insidepro.com/eng/egb.shtml

http://whitepixel.zorinaq.com/

因此,假设您没有将密码存储为旁边的哈希。攻击者仍然可以暴力破解加密的 AES 密钥,但如果用于计算加密的计算量明显高于散列,则暴力破解可能不可行。像 MD5 和 SHA1 这样的哈希算法是为速度而设计的。因此,真正归结为哪种算法的计算复杂度更高,该方案如何为您提供保护。

但是,这两种算法都可能落入密码长度小于 8 个字符的范围内。对于某些算法,一个 7 位密码,大小写混合,所有符号在 GPU 上只需要 7 个小时。如果这些信息足够重要,那么等待的时间并不长。

顺便说一句,加盐无济于事,因为它以明文形式存储,因此您必须假设攻击者可以知道它。salting 唯一能做的就是防止彩虹表攻击,现在我们可以暴力破解它们,这有点毫无意义。