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

Database design 需要一个独特的&;增量用户ID/salt-我应该在服务器端还是在数据库中生成?,database-design,Database Design,全部, 这是一个相当具体的问题,我怀疑没有完美的答案 目标:对于一个网站,我想在用户注册期间生成一个唯一的字符串,该字符串是增量的(因此没有GUID)。这个字符串将成为数据库用户表中的主键,并且还将用于在散列之前对密码进行加密。用户无法看到用户ID-它仅用于内部目的 问题:我应该在哪里以及如何生成字符串?我正在考虑的选择是: 1-使用uniqid(“”)生成PHP代码。 我可以设置一个循环,只要插入失败,就可以重新尝试插入新记录(即,当用户ID已经存在时,如果两个用户试图在同一微秒内完全注册…。

全部,

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

目标:对于一个网站,我想在用户注册期间生成一个唯一的字符串,该字符串是增量的(因此没有GUID)。这个字符串将成为数据库用户表中的主键,并且还将用于在散列之前对密码进行加密。用户无法看到用户ID-它仅用于内部目的

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

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

  • 我可以使用userID对pw进行加密,而无需点击db。用户注册的理想情况是单个db事务
  • 字符串的格式(长度)已知
  • 字符串不是随机的,但足够复杂,可以成为一种好的盐
反对:

  • 该字符串不包含任何容易获得的信息,否则我会发现这些信息很有用。这一事实本身可能会否定它的连续性带来的任何好处,因为我不太可能查询唯一ID的范围,如果它们在其他方面毫无意义的话
  • 如果代码是分布式的,我会冒冲突的风险。(SQL将阻止注册实际冲突,但可能会减慢速度。)
2-使用自动递增标识或类似字段在MySQL中生成。
优点:

  • 没有碰撞减慢注册速度的风险
  • 生成的数字包含有用的信息,即用户的排名
缺点:

  • 作为pw散列过程的一部分,该字段起初并没有增加太多的复杂性
  • 字符串长度随时间而变化
  • 我需要查询数据库中的字符串,以便进行satting和hashing操作——因此每个注册至少命中表两次。(我可以在php中生成一个不同的字符串来创建一个salt,但这样我就多了一个列)
我没有足够的知识或经验来权衡这些利弊,我肯定我错过了一些。如果您能给我带来任何帮助,我将不胜感激

干杯


JDelage可能不是您想要的答案,但是考虑到salt应该由随机位组成,我不确定使用递增整数或字符串是否是最好的选择。为什么不直接使用用户表的(自动递增)主键作为用户id,并使用单独生成的salt进行哈希?我认为这也将解决你在问题中提到的许多权衡问题


编辑:再考虑一下,把salt作为一个用户id完全违背了添加salt的目的:如果你的数据库被破坏了,那么任何黑客都可以访问你的salt。我认为一个更好的计划是使用一个salt,可能是硬编码的代码(因此不在db中)来散列所有用户密码。

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

在PHP中这样做意味着随着用户数据库的增长,您需要运行的查询数量也在增长,以确定下一个可用的数量是多少。如果你有50000个用户,那就需要运行很多查询。还有碰撞的问题

至于你使用MySQL自动增量的缺点

  • 更改字符串中的单个字符将显著更改哈希结果
  • 为什么这是一个问题
  • 您不必运行另一个查询来获取自动生成的ID,只需使用
    mysql\u insert\u ID()

  • 一般来说,最好为每个用户创建一个唯一的随机salt。这将解决上述所有问题,并且更加安全。

    请参阅Ahmet alp Balkan对我的另一个问题的回答:。答案表明uniqid(“”)是正确的方法,因为在给定的微秒内发生碰撞的风险最小,甚至不存在。

    使用单个salt会更糟糕-请参见此处:最好为每个用户使用唯一的随机salt,即使该salt以纯文本形式存储在数据库中