需要一个独特的&增量用户 ID / salt - 我应该在服务器端还是在数据库中生成?
所有,
这是一个相当具体的问题,我怀疑没有完美的答案。
目标:对于一个网站,我希望在用户注册期间生成一个唯一字符串,该字符串增量 (所以没有 GUID)。该字符串将成为数据库用户表中的主键,并且还将用于在散列之前对密码进行盐处理。用户 ID 对用户不可见 - 它仅用于内部目的。
问题:我应该在哪里以及如何生成字符串?我正在考虑的选项有:
1 - 使用 uniqid("") 在 PHP 代码中生成。
我可以设置一个循环,只要插入失败(即,当用户 ID 已经存在时,如果两个用户尝试在同一微秒精确注册...),它就会重新尝试插入新记录。
优点:
- 我可以使用 userID 来加盐 pw,而无需访问数据库。用户注册的理想情况是单个数据库事务。
- 该字符串具有已知的格式(长度)。
- 该字符串不是随机的,但足够复杂,可以成为很好的盐。
缺点:
- 该字符串不包含任何我可以轻松获得的有用信息。仅这一事实就可能会抵消顺序的任何好处,因为如果唯一 ID 的范围没有意义,我不太可能查询它们。
- 如果代码被分发,我就有发生冲突的风险。 (SQL 将防止注册实际冲突,但可能会减慢速度。)
2 - 使用自动增量标识或类似字段在 MySQL 中生成。
优点:
- 没有碰撞风险会减慢注册速度。
- 生成的数字包含有用的信息,即用户的排名。
缺点:
- 该字段作为 pw 哈希过程的盐,一开始并没有增加太多复杂性。
- 字符串长度随时间变化。
- 我需要在数据库中查询字符串才能进行加盐和散列 - 因此每个注册至少会命中表两次。 (我可以在 php 中提出不同的字符串生成来创建盐,但这样我就会再有一个专栏)。
我没有足够的知识或经验来权衡这些利弊,而且我确信我错过了一些。我将不胜感激您可能带来的任何帮助...
干杯,
JDelage
All,
This is a fairly specific question and I suspect there's no perfect answer.
Goal: For a website, I want to generate during user registration a unique string that is incremental (so no GUID). This string is going to be primary key in the user table in the database, and is also going to be used to salt a password before hashing. The userID is not visible by the user - it's used only for internal purposes.
Question: Where and how should I generate the string? Options I'm considering are:
1 - Generate in the PHP code using uniqid("").
I can set up a loop that re-attempts to insert the new record as long as the insert fails (i.e., when the userID already exists, if two users attempt to register exactly at the same microsecond...).
Pros:
- I can use the userID to salt the pw without having to hit the db. Ideal case for user registration is a single db transaction.
- The string has a known format (length).
- The string is not random but is complex enough to be a good salt.
Con:
- The string doesn't contain any easily available information that I could otherwise find useful. That fact alone might negate any benefit from it being sequential, since I'm less likely to query for ranges of unique IDs if they are otherwise meaningless.
- I risk collisions if code is distributed. (SQL will prevent actual collisions from being registered, but it might slow down things.)
2 - Generate in MySQL using an auto-increment identity or similar field.
Pros:
- No risk of collision slowing down the registration.
- The number generated contains useful info, i.e., the rank of the user.
Cons:
- The field doesn't add much complexity at first as a salt for the pw hashing process.
- String length varies overtime.
- I need to query the db for the string in order to do the salting and hashing - so each registration hits the table twice at least. (I could come up with a different string generation in php to create a salt, but then I would have one more column).
I don't have enough knowledge or experience to weigh those pros and cons, and I'm sure I'm missing some. I would appreciate any help you may bring...
Cheers,
JDelage
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
可能不是您想要的答案,但考虑到盐应该由随机位组成,我不确定使用递增整数或字符串是最好的选择。为什么不直接使用用户表的(自动递增)主键作为用户 ID,并使用单独生成的盐进行哈希处理?我认为这也将解决您在问题中指出的许多权衡。
编辑:再多考虑一下,将盐作为用户 ID 就完全违背了加盐的目的:如果您的数据库遭到破坏,那么任何黑客都可以访问您的盐。我认为更好的计划是使用单个盐,可能在代码中硬编码(因此不在数据库中)来散列所有用户密码。
Probably not the answer you are after, but given that a salt should be composed of random bits I'm not sure that using an incrementing integer or string is the best thing to do. Why not just use the (auto-incrementing) PRIMARY KEY of your user table as a user id and use a separately generated salt for hashing? I think this will also resolve a lot of the trade-offs you have noted in your question.
Edit: Thinking about this a bit more having the salt as a user id completely defeats the point of salting stuff anyway: if your db is compromised then any hacker will have access to your salts. I think a better plan is to use a single salt, possibly hard-coded in code (so not in the db) to hash all user passwords.
您希望 MySQL 将其作为自动增量进行管理。
在 PHP 中执行此操作意味着,随着用户数据库的增长,您需要运行以找出下一个可用数字的查询数量也会增长。如果您有 50,000 个用户,则需要运行大量查询。并且存在碰撞问题。
至于使用MySQL自动增量的缺点,
一般来说,您最好为每个用户创建一个唯一的随机盐。这将解决上述所有问题,并且更加安全。
You want to MySQL to manage it as an auto-increment.
Doing it in PHP means that as your user database grows, the number of queries you need to run to figure out what the next available number is grows. if you 50,000 users, thats a lot of queries to run. and there are issues with collisions.
As to your cons using MySQL auto-increment
mysql_insert_id ()
In general, you'd be better creating a unique random salt for each user. that will solve all the above issues, and be more secure.
请参阅 Ahmet alp Balkan 对我的其他问题的回复: PHP - Is uniqid("") 是生成唯一且顺序密钥的良好实用解决方案服务器端?。答案表明 uniqid("") 是正确的方法,因为给定微秒内发生碰撞的风险很小甚至不存在。
Please see Ahmet alp Balkan's response to my other question here: PHP - Is uniqid("") a good practical solution to generate a unique and sequential key server side? . The answer suggest that uniqid("") is the right approach as the risk of collision during a given microsecond is minimal to nonexistent.