5

我要求允许用户在单个设备上使用 4+ 数字 pin 样式的密码。显然,这是一个直接用于保护其服务器端帐户的错误密码,因此我想将此 PIN 码“锁定”到特定设备,以便某人必须同时拥有 PIN 码和设备才能登录,以及在哪里可以访问设备无法访问 PIN。此外,他们已经有一个更传统的用户名/密码登录,并且通过在设备上注册,他们正在向这个现有帐户添加一组新的登录凭据。所以这是我目前的计划:

  1. 在本地设备注册过程中,本地生成强密码。
  2. 将此生成的强密码作为服务器端设备特定帐户密码发送到服务器。
  3. 使用他们提供的 4+ 位密码对生成的强密码进行本地对称加密。
  4. 将此加密的强密码存储在本地设备上。
  5. 在该设备上的后续登录过程中,用户提供相同的 4+ 位密码,用于解密先前存储的强密码,并将强密码发送到服务器进行登录。

所以我相信这可以达到强大的服务器端密码要求。但是,在注册过程之后,我还需要尽我所能保护客户端设备免受入侵(在注册过程之前/期间被入侵的设备是一个失败的原因)。显然,使用 4 位加密密钥,只有 10,000 种可能的组合,因此攻击者很容易能够非常快速地尝试对本地加密的强密码的每种组合。我想知道的是我是否必须选择特定的对称加密方案和/或生成的密码格式,以便攻击者无法仅从本地数据中判断出 10k 次解密尝试中哪一个是正确的?即,他仍然必须在服务器端登录时尝试每一个 10k 密码。

此外,这种方法有什么明显的错误,或者是实现这些要求的更标准的方法吗?如果有标准方法,是否有适用于这种方法的标准 .NET 库?

4

2 回答 2

4

您可以在本地设备中存储盐并使用 PBKDF2 计算 key1。然后使用该密钥服务器端计算 key2,使用单独存储的盐。由于 key1 从未被存储,因此攻击者没有所需的信息。

于 2012-11-27T23:15:52.443 回答
2

您的解决方案是“糟糕的”,因为无论您使用的加密多么“强大”,攻击者必须搜索的密钥空间都非常小。即使使用 8 位数字密码,也只有 10^8 或一亿个可能的密钥。

我的方法会有所不同。我首先要问“为什么要在设备上存储任何凭据?” 我不相信这个问题有一个好的答案。

而是考虑这个解决方案:

用户想要激活 PIN。首先,他选择PIN;让我们称他的选择为 N。他联系您的 Web 服务,用他的用户名和密码标识自己并发送 N。

在服务器端,您生成一个随机字符串,我们称之为 X。您将 X 和 N 连接起来,然后使用 SHA-256 之类的东西对其进行哈希处理。我们将结果称为 H。服务器现在存储 (X, H)。请注意,您的服务器不存储PIN。

稍后,当用户打开移动设备并输入他的 PIN 时,该设备会联系您的 Web 服务并说:“我即将为用户 'Nik Bougalis' 执行 PIN 验证。给我一个挑战!”

服务器为此身份验证创建一个状态:它定位帐户记录,并找到 X 值并发送给用户“X,R”,其中 R 是为此状态生成的随机数。

用户输入他的 PIN,我们称之为 P。移动设备现在连接 X 和 P,并使用服务器使用的相同算法对结果进行散列,生成 H。它现在组合 H 和 R,并对结果进行散列。这会生成一个新的哈希,我们称之为 V。

移动设备将 V 发送到服务器。服务器将数据库中的 H 值和与状态关联的 R 组合在一起,对组合进行散列处理并将其与 V 进行比较。如果它们匹配,则在移动设备中输入的 PIN 是正确的,并且您授予用户访问权限。如果它们不匹配,则输入的 PIN 不正确。

这种方法的优点是服务器可以限制身份验证尝试并减缓暴力攻击。它甚至可以在尝试多次失败后锁定帐户,需要密码才能解锁。

如果您通过 SSL 进行整个交换,您可以跳过发送随机值 R,尽管计算成本非常低,我还是将其包含在内。

一个潜在的缺点是,如果设备无法与服务器对话,则用户无法使用 PIN 进行“登录”。我不知道您是否有允许离线登录的要求,但根据您的特定应用和市场,这可能没什么大不了的——有些人甚至可能称之为优势。

需要明确的是,这不是“超级防弹解决方案”。如果有人闯入并获得对包含 H 值的表的访问权限,他们可以在不知道 PIN 的情况下冒充用户。如果这是一个问题,那里有一些解决方法。

如果您真的对非常高的安全性感兴趣(我怀疑您是,因为您正在考虑使用 4 位 PIN),则可以使用更高级的算法来执行零知识身份证明。

于 2012-11-27T23:55:55.693 回答