我熟悉密码哈希、使用盐、bcrypt 等。
但是,这似乎无法存储 4 位数的 pin 码,因为攻击者可以很快尝试所有 10,000 种组合。有什么我遗漏的或者这通常是如何完成的?
我熟悉密码哈希、使用盐、bcrypt 等。
但是,这似乎无法存储 4 位数的 pin 码,因为攻击者可以很快尝试所有 10,000 种组合。有什么我遗漏的或者这通常是如何完成的?
如果您担心“数据库泄露”的情况(而不是在线破解向量,可以通过每个用户、每个 IP、每个站点的速率限制和锁定来缓解),那么您是对的,散列是不够的.
即使使用最复杂的哈希和加盐序列,例如 bcrypt(pbkdf2(sha256(pin),salt1),salt2) 你仍然容易受到任何可以看到(例如从源代码/文档泄漏)的人的攻击使用过的以及谁能找到你的盐(通常存储在同一个数据库/表中)——他们可以运行相同系列的散列,即使每个散列需要一分钟,也只需要 7 天就可以全部尝试。因此,您基本上将依赖于默默无闻的安全性。
在这种情况下,值得使用密钥加密密码哈希(可以与源代码分开保存,只有受信任的“生产安全操作”用户才能访问,永远不会在预生产环境中重复使用,定期更改,等等。)。该密钥需要存在于验证/更新 PIN 码的服务器上,但它可以与用户/PIN 数据库分开保存(例如,在加密的配置文件中),这意味着 Little Bobby Tables 不会自动获取当他通过 SQL 注入捕获整个 T_USERS 时,或者当有人从您的系统管理员的办公桌上抓取带有 DB 备份的 DVD 时,可以访问它。
[通常不建议对散列进行加密,因为最好使用安全散列、良好的盐和强密码/短语,并且对散列进行加密可能会给人一种虚假的安全感。但是如果你不能有强密码,那么就没有很多其他选择了——乞丐不能选择……]
您可以将 PIN 与密码结合使用——但在这种情况下,为什么还要使用 PIN 呢?只需要一个强字母数字密码。(当然,如果 PIN 与智能卡或令牌或类似物结合使用,那么它可以增加整体安全性。)
我们可以使用更大的(6/8 位)PIN。使纯数字 PIN 免受暴力破解是不可行的:在每秒 1B 的哈希值下,我们需要 16 位或更多数字才能将暴力破解时间超过一年。但是添加更多数字可能足以使在线攻击更容易检测和阻止 - 只有 10K 组合很难将“慢速”阈值设置得足够低以使攻击不可行。不幸的是,您可能有物理限制(硬件选择),从而排除了更长的 PIN。
诸如 bcrypt 之类的密码散列方案旨在在以下情况下提供一些安全性:攻击者可以读取您存储的任何信息来验证密码(例如,他通过 SQL 注入攻击获得数据库的转储)。使用 4 位数的 PIN,熵太低,无法在这种情况下提供很大的阻力,即使有大量的盐和圣经量级的迭代计数。因此,如果您使用 4 位 PIN,那么您已经假设攻击者无法访问密码验证信息,在这种情况下,您可以简单地“按原样”存储 PIN。
即使攻击者每次猜测都必须经过正常的身份验证过程(这是在线字典攻击:对于每次猜测,攻击者必须与用户或服务器或两者交互),10000 个可能的 PIN 是一个非常低的数字。因此,只有通过强制延迟才能实现适当的安全性——极端情况是智能卡通常会做的事情,即在三个错误的 PIN 后将自己锁定(锁定的智能卡就像无限延迟)。这对于网络服务来说是微妙的,因为您不希望人们能够随意锁定其他人的帐户。
限制此类攻击的两个常见因素是:
您没有说明您的应用程序是什么,但您可以考虑使用专用的后端服务器来验证引脚。
然后,您可以限制对该服务器的访问,而不是对前端 Web 服务器的访问。您可以在 pin 检查服务器上实施诸如速率限制之类的限制,这样即使前端服务器被攻击者接管,他们也会遇到暴力破解 pin 的问题。