我有一个数据库表,其中有一个简单的递增整数作为主键(1,2,3等)。这些数字代表一所大学的校友,其中包含记录中的个人信息。我被要求在向用户显示时(在他们查询数据库之后)给每条记录一个唯一的ID,但ID不能是主键,而且必须是一致的。
例如,如果某人检索到具有任意ID 88gh344r的记录,则再次进行搜索并再次检索记录88gh344r,他们需要能够说“那是同一个人”。由于人们需要能够识别从一次搜索到下一次搜索的标识符,因此ID不能长而复杂。
我想到了三种方法:
创建一个包含主键和随机数字序列的额外表,并获取查询以检索与主键等效的随机数。
使用MySQL的SHA2或AES加密主键,但这些主键产生长字母和数字序列。
使用PHP中的Base64加密等方式在查询中动态加密主键。
哪一种最好,或者我错过了更好的方法?
答案 0 :(得分:1)
我实际上只是在一个URL缩短器上写了一个简短的tut,它在此基础上工作,使用recid作为种子。您可以使用该函数创建查找键并将其作为“引用”键存储在数据库中,代码为here
答案 1 :(得分:1)
如果您这样做是为了保护隐私,那么您将前往主要的fsckup。最蹩脚的脚本小子写一个简单的程序,只是尝试每一个可能的“哈希”,下载你的整个列表不会很久。
您应该查看正确的访问控制,以便人们只能看到他们可以看到的内容。
答案 2 :(得分:1)
如果我理解正确,你的主要目标不是揭示主键,而是在与用户沟通时使用别的东西。
最简单的方法:
在表格中添加一个CHAR列,并选择一些您想要其他标识符的长度,例如CHAR(16)。
为该列提供UNIQUE索引,以便您不会有任何重复项。
每行生成一个长度为16的安全 * random *字符串并更新该行。
请勿散列普通主键。如果键从1,2,3开始,那么每个人都可以通过计算1,2,3等的哈希值来匹配id
到hash
另一个问题是,如果您在表中已经有200行并且添加1,则攻击者可以自动将主键201与刚出现在列表中的随机字符串相关联。
另一方面,为什么你需要首先隐藏主键。也许您应该在列中加密个人用户数据?
答案 3 :(得分:0)
不要太复杂。
考虑一下:
为用户提供备用映射密钥。这可以是临时会话映射和/或辅助唯一密钥(但不 PK,并且可能在同一个表中,也可能不在同一个表中),并且当然应该与域唯一。
访问令牌,每个项目随机生成但不必是唯一的,它与暴露的id的简单PK结合使用。如果需要,可以通过适当的转换使其看起来非常漂亮。访问令牌也可以视为单独的值。
我喜欢第二种方法。在这两种情况下,尽管在第二种形式中存在更多偶联,但它并不是暴露的“直接PK”。
这两个都会阻止“知道”基于序列的下一个密钥,但猜测/暴力与域的大小有关:正如其他人所说,这不应该用作主要安全层
快乐的编码。
答案 4 :(得分:0)
你可以在用户ID * 100或其他东西上做基数36编码。
用户ID 26 = 208 userid 3 = 8C
http://www.translatorscafe.com/cafe/units-converter/numbers/calculator/decimal-to-base-36
答案 5 :(得分:0)
您可以将散列值或加密值截断为所需的长度,但两者都可能会发生冲突。如果你有200万条记录,那么你有8个基数为36的数字,大约有50%chance of a collision。如果你没有转换为base-36并且只取八个十六进制数字,你只需要8万条记录。
对于随机数,您没有此问题,因为您可以在列上放置唯一性约束,并在发生碰撞时生成新数字。
答案 6 :(得分:0)
经过 2 个月的搜索,我找到的简短答案是 hashids
,您可以为 https://hashids.org/ 中的每种语言安装它。其选项是:
注意:对于 php
,建议为您的网站主机激活 bcmath
和 GMP
扩展,但无需GMP
。