【问题标题】:Reasonable Security for a shared user identification token?共享用户识别令牌的合理安全性?
【发布时间】:2013-10-25 21:11:24
【问题描述】:

我遇到了一个奇怪的加密问题,我可能做得比需要的多,我将把这归咎于我目前的低烧。我真的不喜欢在没有至少一些审查的情况下在任何与加密相关的事情上推出自己的解决方案。

我正在实施用于集成第三方服务的 SSO 解决方案,其中我根据我们自己的身份验证平台对用户进行身份验证,当用户对其进行正确身份验证时,该平台会返回给我有限数量的一致可用变量。

保证始终代表给定用户的其中一个是他们在我们网络上的login ID。在此上下文中允许的其他任何一项都不能保证对于给定用户保持不变。

我无法将login ID 以明文形式存储在第三方服务上作为共享令牌。 (在你质疑原因之前,有一个非常简单的原因:法律不喜欢它......虽然这个标识符是专门为不敏感 FERPA 而创建的,但它基本上只被删除一次)

我可以散列它。由于可能有充分的理由不将其以明文形式存储在其他地方,因此我想至少合理地对其进行哈希处理。通常,如果给定用户有其他一些非敏感标识符,我可以对敏感信息进行加密(例如,如果它是密码)并将该 salt+hash 和 PK 非敏感标识符存储在一个表中,然后查看在进行比较时,它会根据非敏感标识符进行备份。

如果没有一个不敏感的标识符来执行检索,我似乎只会在没有唯一盐的情况下进行基本的哈希操作(我仍然可以给它们添加胡椒粉)。我存储在自己的数据库中的任何内容都与作为令牌传递的内容一样容易受到攻击,因此创建原始login IDs 到加盐和散列login IDs 的映射表毫无意义。针对我存储的每个盐+哈希盲目地测试给定的哈希是荒谬的。

我可以继续使用 SHA2 和 login IDs 并收工(毕竟,这些只是“只是”登录 ID 而不是密码——而且该解决方案被认为至少足够了) ,但我想知道这种情况是否有更好的解决方案?

【问题讨论】:

  • Anything I store in my own DB would be just as vulnerable as what is being passed as a token 是什么让你这么说?第三方系统可以访问您的数据库吗?
  • 不,但是如果我的数据库被入侵,那么问题就和第三方系统被入侵一样糟糕(假设两者都被完全入侵)。我很乐意假设我们正在使用的数据库更安全,但考虑到环境,这将是一个坏主意......而且一般来说做出这种假设只是一个坏主意。

标签: php security cryptography single-sign-on


【解决方案1】:

我想你应该知道这个:letter from US Department of Education to University of Wisconsin-River Falls:

我们认为 FERPA 允许机构指定和披露 作为“目录信息”的唯一个人标识符,例如 学生的用户或帐户登录 ID(或用作 登录ID),只要不能使用标识符,单独站立, 由未经授权的个人访问非目录 来自教育记录的信息。换句话说,如果学生必须 使用共享机密,例如 PIN 或密码,或其他一些 学生独有的身份验证因素,以及他们的个人 标识符以访问他们在学生信息中的记录 系统,那么该标识符可以被指定和公开为 FERPA下的目录信息符合要求 § 99.37 的规定。 (为学校官员提供津贴 单独使用学生公布的个人标识符,就像他们一样 使用学生的姓名,以获得学生的教育 记录,只要学校官员有合法的教育 符合法规第 99.31(a)(1) 条的利益。)

相反,如果机构允许学生接受自己的教育 使用个人标识符但不使用密码的记录 或其他验证学生身份的因素(或者如果 标识符本身也用于验证学生的身份 身份),则该标识符可能不会作为目录公开 FERPA 下的信息,因为它可能导致披露 受保护的信息给学生以外的人,因此会 是“如果披露是有害的或侵犯隐私”。 (一些 机构可以继续使用学生的“官方身份证号” 这种方式。)在这种推理下,一个机构允许 学生(或任何其他方,就此而言)获得访问 通过提供公开可用的信息来记录教育记录, 例如学生的姓名或公开的电子邮件地址,没有任何 额外的身份证明或身份验证,可能有政策或 违反 FERPA 的做法,因为它可能导致披露 向未经授权的接收者提供教育记录。

但是,如果这不可接受,请考虑额外的临时 ID(共享密钥)。

您可以使用临时分配给用户(很可能通过某种查找表)并在合理的时间间隔内清除的随机令牌(以时间和用户 ID 为前缀以避免检查冲突)。

如果您仍然不想要任何与用户相关的东西,即使是暂时的,您也不能使用哈希,因为哈希是不可逆的。您将无法针对每条记录测试哈希,这在技术上是不可行的。

最后,您可以使用哈希 + 随机令牌和用户 ID,类似于 SSO,但使用存储在服务器上的代码或配置中的密钥加密用户 ID。这样,攻击者必须同时访问数据库和您的代码或配置才能使用数据。理想情况下,每天更改密钥。

【讨论】:

  • 我们知道这一点,从技术上讲,我们使用的 ID 不被认为是直接 FERPA 敏感的,主要问题是即使在那时,由于一般的安全性,法律对此也不满意担忧和“曾经移除”的 FERPA 关系。我可以实现一个查找表,但那时我仍然关心我们自己网络上的数据库安全性,就像我将它存储在异地一样,所以我很好奇在某种情况下最佳实践散列策略是什么像这样,被散列的实际上也是标识符。
  • @taswyn,如您所知,SSO 除了使用用户 ID 外,还使用随机令牌。随机令牌存储在服务器上,与用户相关联。我建议删除用户 ID 并仅使用哈希 + 随机令牌(仍与服务器上的用户相关联)。这不会比 SSO 实现更安全。您将无法仅在一侧散列某些内容,而无法找到记录以测试散列。您必须测试所有记录,这在技术上是不可行的。您需要将该令牌或哈希与 id 链接并保护数据库。
  • @taswyn,我能想到的唯一另一件事是使用令牌和用户 ID(曾经删除的那个),类似于 SSO,但使用存储在代码(或配置)。这样,攻击者将不得不破坏您的数据库和代码。您甚至可以每天更换密钥。
  • 后一个建议是我已经想到的,就从代码(或者可能从从非网络可读位置加载的配置文件)中添加散列而言。就前者而言,关于没有语义连接的查找表,它大约是我正在寻找的一半......但它也可能是我在降低风险方面所能得到的最好的。那时我仍然担心将 ID 散列到我自己的数据库中的最佳方法是什么,但除了基本的胡椒和 SHA2 散列之外,可能不值得担心。
  • 我已经回顾了这一点,我必须补充一点,任何基于时间变化的东西似乎都不可行,即使对于查找表:不将登录 ID 存储在原始要执行基本查找,无法确定任何给定登录 ID 在什么时间(或哪一天)被散列,因此每个潜在的日期或时间(或其相关密钥)都必须作为盐尝试为了寻找碰撞。我只是不认为有任何方法可以在本地存储登录 ID,或者以其他方式存储比现有更多的熵,并且仍然能够执行查找。
【解决方案2】:

目前实施的解决方案

login ID 目前正在通过一系列算法运行,以创建一个独特的盐,该盐可以在运行时基于给定的原始login ID 重新生成,从而实现可重复的查找过程。加上盐和胡椒,login ID 被 bcrypt 散列。

已知问题

低熵(仅依赖于login ID 的固有熵)和创建盐的算法过程严重限制了此加密过程的强度:了解创建盐的过程和价值辣椒,可以为这些哈希创建一个彩虹表。尽管如此,任何标准的预先生成的彩虹表都不起作用:它必须为这组哈希定制完成,并且需要足够的编程知识/足够灵活的生成器来复制盐创建过程。使用 bcrypt 和自定义 salt 例程有望使该过程比检索相关值更耗时。

不幸的是,这本质上是通过默默无闻的安全性,逐渐地。但这是我目前能想到的最好的了。

进一步考虑

根据 Marcus Adams 的回答,一种可能提高安全性的可能性是将散列的 login IDs 存储在查找表中,然后仅将完全随机/唯一 GUID 样式的令牌传递给第三方软件以用于 SSO 目的.这将消除在传输中拦截散列 login ID 的机会(开始时相对较低,因为其中的每一步都是通过 https 进行 SSL 编码的,并且散列 login ID 被折叠到通过 rijndael 加密的 SSO 有效负载中,并且发送前的 PSK)。虽然这消除了第三方妥协导致潜在违反login IDs 的可能性,但它只会将这种潜力转移到我们的系统中,我们不能假设这些系统必然更安全。鉴于当前的解决方案需要对源代码进行妥协以找到胡椒和盐算法,并且任何此类妥协也能够揭示任何数据库密钥,使用查找似乎没有真正增加安全性任何潜在的全面妥协的表格。

深入分析确切我实施的攻击有多大风险超出了我自己的密码学知识或我目前有时间投入的工作。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-12-18
    • 2021-06-24
    • 2011-10-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-08
    相关资源
    最近更新 更多