需要一个独特的&增量用户ID / salt - 我应该生成服务器端还是数据库?

时间:2011-04-05 10:38:18

标签: database-design

所有

这是一个相当具体的问题,我怀疑没有完美的答案。

目标:对于网站,我想在用户注册期间生成 增量< 字符串 增量< / strong> (所以没有GUID )。此字符串将成为数据库中用户表的主键,并且还将用于在散列之前对密码进行加密。用户看不到userID - 它仅用于内部目的。

问题:我应该在哪里以及如何生成字符串?我正在考虑的选项是:

1 - 使用uniqid(“”)在PHP代码中生成 我可以设置一个循环,只要插入失败就重新尝试插入新记录(即,当用户ID已经存在时,如果两个用户试图准确地注册相同的微秒......)。 优点:

  • 我可以使用userID来加密pw,而不必点击db。用户注册的理想情况是单个数据库事务。
  • 字符串具有已知格式(长度)。
  • 这个字符串不是随机的,但是复杂到足以成为一个好的盐。

骗局:

  • 该字符串不包含任何我认为有用的易于获取的信息。仅这一事实可能会否定顺序带来的任何好处,因为如果它们没有任何意义,我就不太可能查询唯一ID的范围。
  • 如果代码是分发的,我冒着冲突的风险。 (SQL将防止实际冲突被注册,但它可能会减慢速度。)

2 - 使用自动增量标识或类似字段在MySQL中生成 优点:

  • 没有碰撞风险会降低注册速度。
  • 生成的数字包含有用信息,即用户的排名。

缺点:

  • 该字段最初并没有增加太多的复杂性,作为pw哈希过程的一个盐。
  • 字符串长度随时间变化。
  • 我需要在db中查询字符串以进行salting和散列 - 因此每次注册至少会对表进行两次打击。 (我可以在php中创建一个不同的字符串生成来创建一个盐,但之后我会再添一个列。)

我没有足够的知识或经验来衡量这些利弊,我相信我错过了一些。如果您有任何帮助,我将不胜感激......

干杯,

JDelage

3 个答案:

答案 0 :(得分:1)

可能不是你想要的答案,但鉴于盐应该由随机位组成,我不确定使用递增整数或字符串是最好的事情。为什么不直接使用用户表的(自动递增)PRIMARY KEY作为用户ID并使用单独生成的盐进行散列?我认为这也将解决您在问题中注意到的许多权衡因素。

编辑:考虑到这一点,将盐作为用户ID完全失败了,无论如何,如果您的数据库被泄露,那么任何黑客都可以访问您的盐。我认为更好的计划是使用单个salt,可能在代码中进行硬编码(因此不在db中)来散列所有用户密码。

答案 1 :(得分:1)

您希望MySQL将其作为自动增量进行管理。

在PHP中执行此操作意味着随着用户数据库的增长,您需要运行的查询数量才能确定下一个可用数字的增长情况。如果您有50,000个用户,那就要运行很多查询。并且存在碰撞问题。

关于使用MySQL自动增量的缺点

  1. 更改字符串中的单个字符将显着改变散列结果
  2. 为什么这是一个问题?
  3. 您无需再运行其他查询即可获取自动生成的ID,只需使用mysql_insert_id ()
  4. 通常,您最好为每个用户创建一个独特的随机盐。这将解决所有上述问题,并且更安全。

答案 2 :(得分:0)

请参阅Ahmet alp Balkan对我的其他问题的回复:PHP - Is uniqid("") a good practical solution to generate a unique and sequential key server side?。答案表明uniqid(“”)是正确的方法,因为在给定的微秒期间碰撞的风险很小甚至不存在。