【问题标题】:Length for unique user ids (created in the range [0..N]) to be long enough for security purposes唯一用户 id 的长度(在 [0..N] 范围内创建)足够长以用于安全目的
【发布时间】:2011-11-28 23:50:36
【问题描述】:

成功注册的人(输入电子邮件地址,创建密码)会收到一个生成的(因此很难猜到前一个或下一个)唯一 id - 一个从 0 到 N。因此,在成功注册后,我们为每个用户提供了 3 个东西:唯一的电子邮件、密码的哈希值和生成的唯一 ID(0 到 N 之间的整数)。电子邮件、密码哈希和 id 存储在数据库中。

问题是:N 应该有多大,以便猜测有效 id 的概率不超过猜测密码(对于任何给定的电子邮件地址)。 (密码只能包含大写和小写字母、数字、8 个以上的符号,如果这很重要的话。)所以,我想要的只是拥有难以猜到的 id。

假设注册用户不应超过 10,000 个(取决于该数字 N 取决于)。现在至少应该有多少位数字包含一个数字N(0..N 是那个长数字唯一的范围)?

我的算法足够好、公平、糟糕还是非常糟糕? 如果我将此问题发布到错误的线程,请告诉我,以便下次我会没事的。

附:当用户成功登录时,来自 db 的 id 将应用于 SESSION 变量。 所有为用户提取个人数据的 sql 请求,将该 id 与该 SESSION 变量进行比较(所以我们现在要提取谁的数据):

"SELECT ... FROM ... WHERE id='".$_SESSION['id']."'"

谢谢。

【问题讨论】:

  • 特定长度是否足以满足安全目的通常无法回答。这取决于它必须有多安全(所以如果数字被猜到,你的系统有多脆弱)以及你能承受多大的数字(为什么让它变得更小(和更不安全)那么有必要?)。尽管从您的描述中我看不出为什么 id 应该是安全的。用户有什么方法可以在会话中放置一个特定的(不是通过正常方式从数据库中检索的)id?如果不是,为什么不采用自动递增的 id?
  • 很遗憾,我不是黑客,对网络浏览器漏洞了解不多。这就是我问的原因。您能否确认(非常高级的用户能够更改他的 session_id)的机会为 NULL?你可能是对的,机会是 NULL,但我不知道真正的答案(我是新手)。
  • 它几乎可以肯定不是null,但是只要它只存储在db和$_SESSION中,它就不会离开服务器是安全的(假设db和脚本在同一台服务器上) .如果服务器端数据被泄露,让用户 ID 难以猜测似乎很愚蠢,因为让服务器端数据更安全更有意义。但是没有冒犯,在不知道自己在做什么的情况下设计安全系统(我假设登录?)是一个坏主意,所以如果你想构建一个合理的安全系统,我真的建议在尝试之前尽可能多地阅读。
  • 你的意思是这样的:devshed.com/c/a/PHP/Creating-a-Secure-PHP-Login-Script-59941(简单而安全的 PHP 登录脚本,包括 cmets),当你说尽可能多地读取气体时?

标签: performance algorithm security validation


【解决方案1】:

如果您将精力放在安全性上,则应将重点放在密码而不是用户 ID 上。

【讨论】:

  • 我相信验证(电子邮件,密码)(存储的哈希而不是密码)-vs.-验证ID几乎相同。我可能错了,世界上的某个人可以妥协一个 SESSION id(现在或以后)以作为注册用户从 db 获取结果。所以,我不希望黑客一旦生成 id,它就存在于数据库中。我的想法错了吗?
  • 即使是银行也提供易于记忆的用户 ID。此外,浏览器倾向于在屏幕上显示用户 ID,同时隐藏密码。如果您需要更高的安全性,请加强密码方案。
【解决方案2】:

为什么它必须有一定的大小?为什么你没有一个自动递增的唯一 ID 并使用它?可能是主键。只要您正确设置表,任何 SQL 数据库都应该能够自动管理。

【讨论】:

  • 我不太了解,也不确定黑客是否可以生成会话ID。这就是为什么我更喜欢唯一的 id,而不是增加 1。
【解决方案3】:

您可以使用字符串代替数字,例如 UUID 之类的字符串应该很难猜到。

>>> import uuid
>>> str(uuid.uuid4()).replace('-', '')
'71dca6b8e3fb41708f93372171f53b9f'
>>>

【讨论】:

  • 使用数字和字符串是等价的。如您所见,您的字符串由 0..9abcdef 组成。所以它是 28+10=38 个符号,但 1 个字节最多可能需要 256 个符号。您仅使用约 10% 的预留空间。所以,数字或字符串都是一样的,问题是多少字节。
  • 是的,我的意思是您可以方便地使用比需要更多的字符,而不是试图找出最佳数字应该是多少。 (一个数字给你2 ** 64选项,一个32个字符的字符串给你10 ** 37倍大的东西)
  • 我认为 64 字节就足够了。但是,最近我阅读了 1024 位(128 字节,对吗?)的 SSL 证书不再好(2010 年之后至少 2048 位还可以)。我的问题中 64 字节是否足够,或者 id 需要 256 甚至 1kb?但是,我相信这有点不同,对吧?这就是我决定问这个问题的原因。谢谢。
  • -1 用于不正确的 api 使用。 UUID 的设计并不难猜,它们应该是唯一的。一些实现是足够不可预测的以用于安全性,而另一些则不是。如果你想要一些安全的东西,请使用加密随机数生成器,如果你想要一些独特的东西,请使用 UUID。如果两者都需要,请使用加密 PRNG 中的长序列。
【解决方案4】:

为了使数字比密码更容易猜测,如果偏执的用户 - 或程序 - 通过真正随机生成密码来选择密码,从所有可能的密码集中,您需要编号最大为 min(可能的密码数,可能的密码哈希数)。如果您在不参考用户名的情况下使用该数字,则还需要它具有很高的概率是唯一的 - 请参阅http://en.wikipedia.org/wiki/Birthday_attack

在实践中,众所周知,计算机系统使用 128 位甚至 64 位数字作为假定不可猜测的标记。看待这个问题的另一种方法是考虑攻击者每秒可能进行多少次猜测,并考虑他们猜测一个 64 位或 128 位数字需要多长时间,无论概率如何让你感到受到威胁。 (与 RSA 一起使用较长的密钥是必要的,因为猜测 RSA 私钥比逐个猜测数字更好)。

【讨论】:

    猜你喜欢
    • 2011-12-27
    • 1970-01-01
    • 2013-02-18
    • 1970-01-01
    • 1970-01-01
    • 2020-08-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多