用户ID混淆
本文关键字:混淆 ID 用户 | 更新日期: 2023-09-27 18:19:40
我想以前有人问过这个问题,但在这里还没有找到合适的答案,也没有时间提出我自己的解决方案。。。
如果我们有一个具有int identity
主键的用户表,那么我们的用户在网站上注册时具有连续的ID。
我们网站上的用户公共资料页面URL:
www.somesite.com/user/1234
其中1234是实际的用户ID。没有任何漏洞可以看到用户的ID本身,但它确实让任何人都能够检查有多少用户在我的网站上注册。。。手动增加数字最终会使我进入一个无效的配置文件。
这就是为什么我把一个可逆的ID映射到一个固定长度的看似随机的数字的主要原因:
www.somesite.com/user/6123978458176573
你能给我指一个做这个映射的简单类吗?当然,重要的是,这个映射是可逆的,否则我必须将映射与其他用户的数据一起保存。
我想避免GUID
GUID的索引搜索速度较慢,因为它们不是连续的,所以SQL必须扫描整个索引以匹配特定的GUID,而只是特定的计算索引页。。。
如果我有ID+GUID,那么我总是需要获取原始用户ID来进行任何有意义的数据操作,这再次降低了速度。。。
数学可逆整数排列似乎是最快的解决方案。。。
我会100%采用"向表中添加GUID列"的方法。为每个当前用户生成一个需要几秒钟的时间,并更新插入过程以为每个新用户生成一。这是最好的解决方案。
然而,如果你真的不想采取这种方法,你可以使用许多模糊处理技术。
简单地对数字的字符串表示进行Base64编码是一种(糟糕的)方法
static public string EncodeTo64(string toEncode)
{
byte[] toEncodeAsBytes
= System.Text.ASCIIEncoding.ASCII.GetBytes(toEncode);
string returnValue
= System.Convert.ToBase64String(toEncodeAsBytes);
return returnValue;
}
static public string DecodeFrom64(string encodedData)
{
byte[] encodedDataAsBytes
= System.Convert.FromBase64String(encodedData);
string returnValue =
System.Text.ASCIIEncoding.ASCII.GetString(encodedDataAsBytes);
return returnValue;
}
糟糕的是,任何拥有半盎司技术知识的人(黑客/脚本儿童往往拥有丰富的技术知识)都会立即将结果识别为Base64,并轻松进行反向工程。
编辑:这篇博客文章用Rails混淆URL中的ID提供了一个非常可行的例子。转换为C#会给你一些类似的东西:
static int Prime = 1580030173;
static int PrimeInverse = 59260789;
public static int EncodeId(int input)
{
return (input * Prime) & int.MaxValue;
}
public static int DecodeId(int input)
{
return (input * PrimeInverse) & int.MaxValue;
}
输入-->输出
1234-->1989564746
5678-->1372124598
5679-->804671123
另一位作者的这篇后续文章解释了如何通过随机XOR来确保这一点,以及如何计算Prime
和PrimeInverse
——我只是使用了原始博客中预先录制的内容进行演示。
-
使用UUID
-
在用户表中为创建另一列,例如64位整数,并用一个随机数填充(每次新用户注册时,生成它并检查它是否唯一)。数字看起来比UUID更好,但需要更多的编码。
-
使用数学。)您可以生成一对数字
X
、Y
,例如X*Y = 1 (mod M)
。例如X=10000000019L
、Y=1255114267L
和M=2^30
。然后,您将有两个简单的功能:
long encode(long id)
{ return (id * X) & M; }
long decode(long encodedId)
{ return (encodedId * Y) & M; }
它将产生几乎随机编码的id。这很简单,但很容易破解。如果有人愿意破解它,他将能够猜测你的数字,并看到编码值。然而,我不完全确定它的复杂性,但正如我所记得的,它不是很容易破解。
我可以建议您改用UUID吗。当您向数据库中添加新用户时,这可以是可索引的,并在存储过程中生成。这意味着要么向数据库表添加一个新列,要么添加一个包含UUID但以用户ID作为相关键的新表。
编辑
如果你真的想避免GUID,那么为什么不在用户访问其配置文件页面时使用"用户名"呢。毕竟,我想,在用户输入有效信息并将数据保存到数据库中之前,您不会为用户分配ID。