使用 V4 UUID 进行身份验证

信息安全 验证 uuid
2021-08-10 05:09:41

我想使用 V4 UUID / GUID 来验证用户。具体来说,用户必须将 UUID 粘贴到文本字段中才能访问他们的帐户。UUID 将在注册时提供给他们。验证时,UUID 将与用户名(公共)结合使用。

假设正常的安全实践已经到位(SSL、保存 UUID 的数据库在静态时被加密、防止暴力攻击、UUID 不会在 URL 中传递等)。假设该应用程序不是用于任何非常重要的事情(银行),但仍然相当重要(为了争论,假设它是域名)。不要担心用户可能遇到的可用性问题。我只是担心安全问题。

  • 鉴于上述情况,这仍然是一个坏主意吗?
  • 你认为这比用户名/密码安全吗?
  • 将两个 UUID 拼在一起会更安全吗?

我的目标是不存储任何类型的个人数据(电子邮件/通行证)。我希望这是一个可行的选择。

4个回答

UUID 通常不保证不可预测性或任何安全属性。正如RFC 4122所说(第 6 节):

不要假设 UUID 很难猜;例如,它们不应该用作安全功能(仅拥有授予访问权限的标识符)。一个可预测的随机数源会加剧这种情况。

您在这里需要的是一个加密安全的随机数生成器一些 UUID 实现是由此类 RNG 驱动的,但这是一种实现选择,而不是保证。ITU 标准明确表示建议使用加密随机数,这显然意味着这不是要求(第 10 页):

强烈建议使用加密质量的随机数,以减少重复值的概率。

事实证明,一些 UUID 实现并不安全。例如,至少某些版本的 Google V8 Javascript 引擎使用非加密 PRNG 来生成随机 UUID该链接描述了如何攻击这样的 UUID——通过几行代码,看到一个这样的 UUID 的攻击者可以在输出该 UUID 时重建 PRNG 的状态,从而使他们能够预测所有后续的 UUID。

因此,我不会将 UUID 用作加密机密——我会直接与加密 RNG 交互,至少要让代码的意图显而易见。

更大的问题是您的用户无法记住这些令牌;他们必须将它们存储在安全的地方,而您不会为此提供任何帮助。这里不明显但实际上非常自然的替代方法是使用基于密码密钥的多因素身份验证系统,例如TOTP例如,如果您构建与Google AuthenticatorAuthy的集成,您的用户将受益于这些供应商的用户端应用程序来存储和管理共享密钥。

您只是在描述一个 UUID 只是成为密码的方案。

除了没有人能够选择“弱”密码之外,没有什么特别安全或不安全的地方,但另一方面,有一半的人会以未加密的方式存储他们的密码。

我真的不明白你为什么要这样对人。拒绝业余爱好者选择他们能记住的密码的机会,也不拒绝专家生成他们认为安全的密码的机会,你不会让自己变得非常受欢迎。

另外,我个人认为个人银行账户密码的价值要低得多(考虑到银行一直在进行二次电汇,至少在欧洲,因为现在有超过 25 年的交易 ID 一次性垫)而不是域控制(我几乎不能毁了通过查看某人的银行帐户来查看某人的业务,除非我打算根据其他信息使用它来惹恼他,但是我可以通过操纵其域的 MX 记录通过我的服务器重新路由他的所有电子邮件并有选择地让他通过CEO 的邮件和回复。哦,你知道,如果他们有在线业务,实际上是在最大程度上滥用他们的网络存在)。

所以:

鉴于上述情况,这仍然是一个坏主意吗?

是的,发明新的身份验证方案通常是个坏主意。

你认为这比用户名/密码安全吗?

取决于您的客户,并且像往常一样,取决于您的攻击场景。

将两个 UUID 拼在一起会更安全吗?

它会导致更长的随机序列,所以是的,但是,为什么不从一开始就使用更长的随机序列呢?

这一切感觉就像你没有想到这一点。

V4 UUID 非常常用于创建 API 身份验证令牌,例如 basic-auth 或 Oauth2 不记名令牌。根据RFC-4122版本 4 UUID 用于从真正随机或伪随机数生成 UUID最常用的 V4-UUID 生成器使用加密安全的随机数生成器。例如github.com/google/uuid使用了crypto/rand包。

对于用户身份验证,一些最佳实践包括强密码策略(最小长度、特殊字符、不允许姓名/生日等)、建议的强密码、至少 2 因素身份验证等。根据用例,V4- UUID 可能是第一因素生成令牌的一个选项。只需确保 V4-UUID 生成器使用密码安全的密码安全随机数生成器即可。

我认为 UUIDv4 不够强大,无法符合某些标准。

例如,RFC6819、OAuth 2.0 威胁模型和安全注意事项 要求

当创建不打算供人类用户使用的秘密(例如,客户端秘密或令牌句柄)时,授权服务器应包括合理的熵水平,以降低猜测攻击的风险。令牌值应 >=128 位长,并由授权服务器生成的加密强随机或伪随机数字序列(参见 [RFC4086] 以获得最佳当前实践)构成。

严格来说,UUIv4 是“>=128 位长”,但我认为其意图实际上是说令牌应该具有至少 128 位的熵。UUIDv6 只有 122 位的熵。

RFC6747,OAuth 2.0 授权框架说:

攻击者猜测生成的令牌(以及其他不打算由最终用户处理的凭据)的概率必须小于或等于 2^(-128),并且应该小于或等于 2^(-160)。

我认为这应该意味着 Oauth 的令牌必须具有至少 128 位的熵,并且应该具有至少 160 位的熵。

请注意,许多 OAuth 实现实际上在实践中使用 UUIDv4 令牌。

如果您想生成随机密码/令牌,我建议您使用类似(Node.js 中的示例):

crypto.randomBytes(160/8).toString('base64').replace(/=/g,'')

您可以轻松调整熵的位数,并且您的令牌比标准 UUIDv4 表示更紧凑(就每字节的熵位数而言)。