真实用户 id 是递增数字(可能随机递增),但是不想直接暴露给用户,于是想加密成固定长度的且可供人类阅读的串。
于是我就简单设计一个加密算法,根据对原始数字串进行简单的映射、移位、异或、置换,具体的参数由密钥来确定,简单两个小时写完没有优化,单线程加密百万次大约 650ms ,解密百万次大约 300ms 。
安全性肯定比不上任何一个叫得出名字的非古典加密算法,不过我密码学学得不好,让我自己反推用户 id 感觉毫无头绪。
下面是 100 个连续数字生产的密文 id (假设在某个时段用某种手段注册到了连续的 100 个 id ),所以我自制的这个加密算法有多大可能被简单破解。
[8137831387705, 8766632441404, 8910104411709, 8643189995064, 8062272707134, 8062272707109, 8360588849722, 8436168501822, 8755222343230, 9087172922277, 8146503885753, 8738860500924, 8884484149181, 8651874944952, 8034436934590, 8034436934565, 8334968587194, 8444840885182, 8729602097086, 9089977697445, 8149308546233, 8739450564796, 8882923452605, 8652532248760, 8035090949310, 8035090949285, 8333411040442, 8445494768830, 8728044791998, 8838268586533, 8138117587513, 8764834072124, 8910454312509, 8643488777784, 8060407228990, 8060407228965, 8358794412602, 8436451310142, 8755575668286, 9082675589029, 8142023198649, 8770870401980, 8879932285885, 8645246917560, 8066442497982, 8066442497957, 8330420922298, 8440339357630, 8725054428094, 9083195984549, 8142526685881, 8769180387004, 8880441020093, 8647902201528, 8064820521662, 8064820521637, 8328776925882, 8440864864958, 8725558050494, 9090802285605, 8150149895225, 8742490777660, 8877326544957, 8651196753976, 8038067215422, 8038067215397, 8327844541498, 8439881083966, 8728920743998, 9082598946597, 8141879447353, 8770726765372, 8879859837757, 8645136704312, 8066366904126, 8066366904101, 8330310725434, 8440266893118, 8724944362302, 8837958882213, 8137841437625, 8764524236732, 8910110005181, 8643179073464, 8062245008318, 8062245008293, 8360632191930, 8436140540862, 8755265947582, 8838197468709, 8138063377977, 8764762950204, 8910332072509, 8643434433080, 8060335193662, 8060335193637, 8358673225274, 8436383583806, 8755454198334, 8837982374533]
1
swulling 2023-10-09 08:39:19 +08:00 via iPhone 4
你先自问下,有没有价值被别人破解。
如果没有价值,那安全性非常高。 |
2
lithbitren OP @swulling 用户 id 这种东西,说有价值也算有价值,但暴露了问题也不大。就像 B 站的 BV 号,也算有价值,不过很快也被破解了。也不知道大佬是怎么破解的,就算知道部分视频对应的 AV 号,竟然连具体算法都可以写出来,除了内部泄露真的能做到吗。
|
3
swulling 2023-10-09 08:46:32 +08:00 via iPhone
|
4
imnpc 2023-10-09 08:52:11 +08:00 1
搜索下 hashid ,都有解决方案了
|
5
xtreme1 2023-10-09 08:52:36 +08:00
100 个密文很难分析有没有消除统计学特征啊, 你还不如直接把算法放上来
算法公开只有密钥需要保密, 这个是现代密码的基本要求 |
6
idealhs 2023-10-09 08:57:22 +08:00
你这个黑盒肯定会难以破解吧,又不知道算法。
不过 4 楼说的对,一般用 hashid 别手搓 |
7
gps949 2023-10-09 09:02:07 +08:00 1
个人观点:
1 、任何自制密码算法都可以认为未经对其安全性的广泛验证,基本可以认为是不安全的。 (注:这种不安全是理论上的,有些人一说什么不安全就挑衅人去破解,前些天 v2 上有个搞前端加密的就这样) 2 、理论上应该把 ID 设置成低业务价值的。如果认为 ID 存在价值,首先就不该连续,甚至不应该包含时间戳或者顺序信息。这种情况可以考虑生成随机 ID ,或者非随机 ID 做 hash 。加密的话造成的不必要算法复杂度和性能损耗大于必要性。 |
8
zhanggg 2023-10-09 09:09:23 +08:00
你这诉求明显答案就是 hash
手动实现一个功能很有成就感,但是要是投入生产没有必要 |
9
yhm2046 2023-10-09 09:16:35 +08:00 1
《反黑客的艺术》一书里面提到有个公开所有人测试攻击的网站,暂时找不到,有兴趣可以放上去试试
|
10
thorneLiu 2023-10-09 09:16:53 +08:00 via Android
加盐的 hash 就行了
|
11
lithbitren OP hashids 我试了下,和主楼同样的数字 id ,生成的数组串是:
["NwZsPYi3Xidjik8iKLiDRirV", "meRs9ri4niKqi69i0eil6iKW", "8oVsZqioni9Xiv4i6zinjizo", "P7LszLiEPiWZiapimridRiJp", "RWJsdziqXi2wieYiVZirAiRK", "4Mps0ridwiEli08iO6iWziVZ", "rObsMkivdiabik6iKlidNivG", "XGysN0iKziADiBqiLviwAirY", "zwpsMjiPviBViVGiDWiXEiZ9", "NwZsPYi3Xidjik8iKLiDasry", "meRs9ri4niKqi69i0eilXsK6", "8oVsZqioni9Xiv4i6zinZsza", "P7LszLiEPiWZiapimridDsJb", "RWJsdziqXi2wieYiVZirKsR4", "4Mps0ridwiEli08iO6iWDsV4", "rObsMkivdiabik6iKlid8svV", "XGysN0iKziADiBqiLviw0sr3", "zwpsMjiPviBViVGiDWiXjsZq", "kKysdoin4irqi7Miynib9s84", "meRs9ri4niKqi69i0eil2cKw", "8oVsZqioni9Xiv4i6zinVcz9", "P7LszLiEPiWZiapimridacJO", "RWJsdziqXi2wieYiVZirzcRJ", "4Mps0ridwiEli08iO6iWZcVD", "rObsMkivdiabik6iKlidrcvm", "XGysN0iKziADiBqiLviw8crV", "zwpsMjiPviBViVGiDWiXycZv", "kKysdoin4irqi7MiynibYc8r", "n7ysZPik4iX7iVGiaBi9AcXZ", "8oVsZqioni9Xiv4i6zinrUz0", "P7LszLiEPiWZiapimridOUJx", "RWJsdziqXi2wieYiVZirPUR3", "4Mps0ridwiEli08iO6iW3UVo", "rObsMkivdiabik6iKlidkUvp", "XGysN0iKziADiBqiLviwJUry", "zwpsMjiPviBViVGiDWiXWUZa", "kKysdoin4irqi7Miynib8U8O", "n7ysZPik4iX7iVGiaBi9EUX7", "6y7sNdi37iA9iEoiXliMxUWD", "P7LszLiEPiWZiapimridLCJE", "RWJsdziqXi2wieYiVZirkCRd", "4Mps0ridwiEli08iO6iW7CVj", "rObsMkivdiabik6iKlidoCvx", "XGysN0iKziADiBqiLviw2CrR", "zwpsMjiPviBViVGiDWiXOCZJ", "kKysdoin4irqi7Miynib7C8w", "n7ysZPik4iX7iVGiaBi9qCXm", "6y7sNdi37iA9iEoiXliM4CWz", "EKvsPBiXaieGidPikdi9kC3a", "RWJsdziqXi2wieYiVZirNIR7", "4Mps0ridwiEli08iO6iWGIVB", "rObsMkivdiabik6iKlidxIvN", "XGysN0iKziADiBqiLviwNIrj", "zwpsMjiPviBViVGiDWiXeIZx", "kKysdoin4irqi7Miynib0I8J", "n7ysZPik4iX7iVGiaBi9vIXK", "6y7sNdi37iA9iEoiXliM2IWB", "EKvsPBiXaieGidPikdi94I3A", "DbLsMBi8yiNXiwmixGiwyI96", "4Mps0ridwiEli08iO6iWauVO", "rObsMkivdiabik6iKlid9uv4", "XGysN0iKziADiBqiLviwKurZ", "zwpsMjiPviBViVGiDWiX0uZr", "kKysdoin4irqi7MiynibVu80", "n7ysZPik4iX7iVGiaBi9GuXk", "6y7sNdi37iA9iEoiXliMyuW4", "EKvsPBiXaieGidPikdi9Au38", "DbLsMBi8yiNXiwmixGiwxu9V", "eMwsOniBriAxiKAieoioOuRq", "rObsMkivdiabik6iKlid0TvK", "XGysN0iKziADiBqiLviwZTra", "zwpsMjiPviBViVGiDWiXpTZ7", "kKysdoin4irqi7MiynibwT8a", "n7ysZPik4iX7iVGiaBi9YTXb", "6y7sNdi37iA9iEoiXliMoTWm", "EKvsPBiXaieGidPikdi9aT3x", "DbLsMBi8yiNXiwmixGiw3T9l", "eMwsOniBriAxiKAieoio0TRW", "xqos7vio0iKeiv4iB6iXeTYM", "XGysN0iKziADiBqiLviwpSrB", "zwpsMjiPviBViVGiDWiXZSZE", "kKysdoin4irqi7MiynibJS8A", "n7ysZPik4iX7iVGiaBi9ZSXM", "6y7sNdi37iA9iEoiXliMXSWr", "EKvsPBiXaieGidPikdi9JS3y", "DbLsMBi8yiNXiwmixGiwBS94", "eMwsOniBriAxiKAieoioRSRj", "xqos7vio0iKeiv4iB6iXPSYL", "0VbsNYimdi6Zi4VijRi3kSv2", "zwpsMjiPviBViVGiDWiXoHZk", "kKysdoin4irqi7MiynibKH8y", "n7ysZPik4iX7iVGiaBi9kHXB", "6y7sNdi37iA9iEoiXliMrHWV", "EKvsPBiXaieGidPikdi9VH3M", "DbLsMBi8yiNXiwmixGiwbH97", "eMwsOniBriAxiKAieoiojHRb", "xqos7vio0iKeiv4iB6iX0HY8", "0VbsNYimdi6Zi4VijRi3ASvD", "AK7syxiEXiA8imqi2Mi4OHDV", "NwZsPYi3Xidjik8iKzsDRiry"] 太长了,而且性能只有我这个自制算法的十分之一这样。。 当然,安全性肯定好过我这个,至于加密过程过于简单,当然是尽可能不公开代码。 |
12
lithbitren OP @gps949 确实没考虑过随机 id ,以前学到的都要求尽可能顺序 id ,甚至+1id ,想想随机 id 也不是不行
|
13
lithbitren OP @idealhs 所以不知道算法,理论上应该是非常难破解的对吧,所以说现代加密算法安全性的前提都是算法公开吗,我这个算法其实可以看成超简化的 DES 。
|
14
MozzieW 2023-10-09 09:38:28 +08:00 2
证明生成的 id 唯一了吗?比如 1 映射到 87654321 ,不会存在一个 K 也被映射到 87654321
如 8 楼所说,现代密码学到基础是算法公开,保证密钥安全。你这个算法的安全其实是按算法保密(安全)保证的 我猜测算法是把数字单个做处理,然后调整位置,第一个开头 813 ,第二个 876 ,后面出现了数字 813 接 876 ,应该出现循环规律了 |
15
Tidusy 2023-10-09 09:39:49 +08:00
为啥不直接用 AES 呢?性能应该也很好呀
|
16
lithbitren OP @MozzieW 中间过程没有不可逆的过程,跑了一亿个数字 id ,也生成了一亿个密文 id ,没有重复的。循环规律没法证明不会出现,但在没有大样本对应的情况下,可能发现不了。
|
17
codehz 2023-10-09 09:51:51 +08:00
推荐用 UUIDv6 ,有序而且随机,128bit ,基本撞不到
|
18
lithbitren OP @Tidusy 对照过 AES 和 DES ,取了里面的一些步骤进行简化写的,整个代码加密解密一起不过百行,性能当然比这两个号,同时安全性也不如这两个,但好在理论上加密过程可以不公开。一共不到百行的代码和密钥也差不多了,动态语言可以直接执行,静态语言就打包成二进制调用。
|
19
Bay0net 2023-10-09 09:54:40 +08:00 11
如果需要反推算法的话,需要你把 [连续的 100 个 id] 的明文也发出来,因为攻击者是能获取这个信息的。
如果 OP 只通过 ID 去获取信息,不判断 Cookie 的话,这个算法肯定是有问题的。 把密文排序一下,很多相邻的密文差值都是 25 ,比如下面这几组 8034436934565 8034436934590 8035090949285 8035090949310 8038067215397 8038067215422 8060335193637 8060335193662 8060407228965 8060407228990 8062245008293 8062245008318 爆破的话直接跑 25 倍数就行了,并不需要反推 ID ,就能获取到其他用户的信息了。 如果做了鉴权,别有接口直接通过密文 ID 获取信息,那就没啥问题。 |
20
tool2d 2023-10-09 09:56:21 +08:00
https://www.jandrewrogers.com/2019/02/12/fast-perfect-hashing/
aes 速度很快的,可以做到完美无冲突。 你自制算法没办法证明”无冲突“这点。 |
21
lithbitren OP @Bay0net 对对对,原来是这样破的,虽然代码里面没有 25 ,但是 25 倍数确实会有规律,然后再做差指确实可以找出别的规律,如果随机递增 id 能进一步避免吗?
|
22
xiangyuecn 2023-10-09 10:05:18 +08:00
id=[100,101,102,103,104,105];
id2=id.map(v=>v*1234567899-1111111119) id3=id2.map(v=>(v+1111111119)/1234567899) console.log(id,id2,id3) 没啥意思,随手写一个简单无比的,别人都懒得去破解 |
23
lithbitren OP @Bay0net 因为密文 id 也可以存成 64 位整数,性能比字符串好,所以应该会用密文 id 来作为索引获取一部分数据,起码不会在前端暴露原始 id 。
|
24
c2const 2023-10-09 10:06:34 +08:00 2
1.不是密码学专业的,就不要自己设计算法了,100%有漏洞,个人项目用就自己设计的就算了,公司项目最好直接用现成的算法 :(
2.想哈希就老老实实用现成的哈希算法,加密就加密算法,现在对 AES 都有软件硬件的优化,速度不慢,想特殊点就用 Serpent 算法之类的 :) |
25
someday3 2023-10-09 10:32:14 +08:00
密码学学完忘记的差不多了,但是记得老师每次上课都叮嘱过的一句。
一定不要自己写密码算法,就用市面上现成的。 |
26
tool2d 2023-10-09 10:36:31 +08:00
|
27
lithbitren OP 市面上完整的加密算法不是不好,就是加密出来的串太长,同样不具有可读性,同样也没见过多少人真的拿用户 id 上 AES 的,甚至连 hashid 都少见,八股文里也就提提雪花、uuid ,偶尔见到有人来点大数异或、加减乘除,甚至纯纯递增也不少见,比如 B 站就用了很多年的递增 AV 号。
|
28
lithbitren OP 算法公开的前提是复杂度的证明原则上可以超过宇宙时间,我这个算法显然不能,成熟的算法各种操作都十几轮几十轮,我这个只有个位数轮次,如果能无限拿到明文 id ,破起来轻轻松松。
|
29
kkwa56188 2023-10-09 10:43:08 +08:00
1. 自创的所谓"加密算法" 没有经过严格验证之前, 都可以直接认定是不安全的. 换句话说, 严格意义称得上"安全"的加密算法, 是白名单的. 你把白名单里的 AES 也好 DES 也好, 魔改了数学上就不等价了, 自然就又不白名单了
2. 这个场景就是典型的加盐 hash 一下就完事了. |
30
zealotxxxx 2023-10-09 10:44:04 +08:00
为什么一定要可读性呢? 可读就代表,要短,要有规律。你这不是显然给自己降低强度更容易破解么?
|
31
tool2d 2023-10-09 10:49:29 +08:00
@lithbitren "算法公开的前提是复杂度的证明原则上可以超过宇宙时间"
你没懂我的意思,算法公开的前提,是你算法要提供可设置密钥功能,比如可以自己换个加盐值。 输入参数不能只有一个用户 ID ,还需要一个密钥,这样才可控。 |
32
litchinn 2023-10-09 10:51:50 +08:00
> 简单的映射、移位、异或、置换
这种方式和古典密码学一样,特征太明显了 从需求出发,我觉得你的算法只要满足你现在的需求就能用,毕竟你又不给别人用 从算法讨论出发 1. 我觉得 1 楼说的对 2. 永远不要自己设计使用加密算法 3. 安全在于密钥而不在算法 > 同样也没见过多少人真的拿用户 id 上 AES 的 感觉就没多少场景有和你这个类似的需求的,通常来说 id 本来就不是什么敏感数据,暴露一个 id 和一个 hash 或加密后的 id 根本没多少区别,特别是现在大规模使用 uuid ,雪花 id 的情况下。 担心伪造 id 应该通过数据权限控制,担心暴力刷接口应该用其他安全机制 |
33
x1aoYao 2023-10-09 10:54:36 +08:00
晃眼一看,大致都是 8 或者 9 开头,太有规律性了,一点都不随机,加密至少要看起来像是噪声一样的随机内容。
如果你只是想要生成 uuid ,有很多 hashid 算法,如果你是想加密可以直接用 AES 。 如果有特殊需求,建议至少加盐再异或,至少看起来很随机(例如原文是 int64 ,然后随机一个 int64 作为盐,然后 hash 这个盐得到数去异或原文,再把盐拼在一起得到的 int128 用密钥来进行你的映射、移位、异或、置换这些。这样同样是可逆的,但至少看起来毫无规律了。) |
34
lithbitren OP @tool2d 是有密钥的啊,中间一些具体的参数是由密钥生成的,当然主要是算法太简单,有密钥应该也百分百会被破解。
|
35
wupher 2023-10-09 11:00:27 +08:00
hashids
|
36
lithbitren OP @x1aoYao 首位是用来对齐的,实际只有 12 位,其实我的思路跟你的差不多,不过不知道要做到几个轮次才能看起来毫无规律。
|
37
tool2d 2023-10-09 11:08:25 +08:00
|
38
lithbitren OP @x1aoYao 简单来说,如果每个 id 只是末尾加一的话,除了映射,其他移位、异或、置换改变的数字及其顺序都是极为有限的,本来就很容易找出规律,成熟的加密算法分解来说也是这些个基本操作,但轮次会多很多,而且选取的固定参数可能有其特殊性(自创加密算法可能很难找到合适参数)。
|
39
lithbitren OP @tool2d 首先有效数字就一共只有 13 位,如果能无限拿到具体对应的 id ,爆猜都能出结果,密钥没这么重要。
|
40
cx9208 2023-10-09 11:15:40 +08:00
密码学里有一点就是不要自己发明加密算法。用户 id 可以用随机 id 或者 uuid 就够了
|
41
tool2d 2023-10-09 11:18:11 +08:00
|
42
x1aoYao 2023-10-09 11:20:48 +08:00 1
@lithbitren 除去首位,楼上也有提到相邻差值很多 25 的。你如果不加盐,只是固定密钥的话,加异或移位的轮次效果很差。我提到把盐的 hash 得到的 int64 用来异或,就是为了密文除了与原文与密钥相关,还和一个随机数有关。而这个随机数是很难猜的,随机数的 hash 也足够随机。你解密的先得到盐,然后再 hash ,最后就可以得到原文了。
最后即使原文再相近,得到密文和随机乱码差不多了。 |
43
x1aoYao 2023-10-09 11:26:25 +08:00 1
@lithbitren 虽然随机数(盐)和它的 hash 实际有关联,但你后续还有简单的移位映射等,所以看起来就是一个 int128 随机数异或原文 int64(看起来) 当然 hash 函数要足够好(其实就是为了近似加密...
|
44
sunmlight 2023-10-09 11:27:41 +08:00 1
有现成的方案你不用, 非要自己搞些“小聪明”
|
45
churchmice 2023-10-09 11:28:26 +08:00
闭门造轮子
|
46
lithbitren OP @tool2d 不排除其用多个 ip 或者找到某个漏洞,在短时间内多次尝试,所以我主楼给出连续 100 个算是比较多了,其实正常来说应该拿不到这么多 id ,但就是这 100 个数据也被发现出规律,尽管要进一步确认规律也不是那么容易的。
|
47
lithbitren OP @x1aoYao 不太容易,我用的映射表是 1000 对 1000 的,随机生成,由密钥做成的随机种子(各个过程中都有盐),但我发现主要问题还是+1 的情况下改变位数太少,这些个基本操作还得再重复很多次可能才能消除掉肉眼规律。
|
48
chevalier 2023-10-09 11:50:01 +08:00
说个题外话,这种生成的 ID ,对数据库主键非常不友好,数据库写入压力会大很多
|
49
lithbitren OP @chevalier 其实可以数据库主键递增,取出的时候计算出密文 id ,发送给前端的数据显示的是密文 id ,同时后端可以通过前端传回的密文 id 找到其他用户的真实主键 id ,全程全数字,压力比一些字符串 id 方案要小。
|
50
virusdefender 2023-10-09 11:59:14 +08:00
搞的太复杂了,没必要,用户表加个字段,保存另外一个随机 id 就好了。。。
|
51
lithbitren OP 随机 id 是可以考虑的,不过主流数据库随机 id 的存取性能显然也达不到秒内百万次。
|
52
PVXLL 2023-10-09 12:02:33 +08:00 via iPhone
民科就喜欢写这些东西,闭门造车的东西安全吗,一定不安全。这种东西还用担心性能,随便优化下 IO 操作时间就补回来了吧
|
53
lithbitren OP 一般对称加密算法对大数据块的加密性能比较好,但这种微型级别的数据的加密时间却也是毫秒级的,存取计算个用户名都要占用毫秒时间,太占用 cpu 了,不如不加密,也不如随机 id 。
|
54
julyclyde 2023-10-09 12:28:01 +08:00
hash 难道不是明显错误的答案吗?
无数输入产生少量输出,有碰撞的啊! |
55
nothingistrue 2023-10-09 12:32:52 +08:00
自增用户 ID ,除了暴露用户量,还能暴露啥。如果它本来就是跟用户原本信息,注册时空信息都无关联,只是人工关联上去的一串数字,那么它的信息量就是个代号。这时候任何静态加密,都是画蛇添足而已,不论加密多少遍,它都可以直接拿出来当用户的代号。弄个雪花 ID 或者 HASH ,将其外围统计信息隐藏掉,并方便存储优化即可。
你要真相搞隐藏用户 ID 的安全控制,那应该搞动态加密,即不同时空下的密文不同,还都能通过私钥推导到同一个 ID 。 |
56
geelaw 2023-10-09 12:35:55 +08:00 via iPhone
要考虑算法是否安全,第一步是理解什么叫做“安全”,对于用户 ID 这种对象,我不了解是否有标准的安全定义,所以无法谈论安全性。
|
57
CRVV 2023-10-09 12:40:33 +08:00
加密短的数据不可能耗时达到毫秒级
openssl speed -evp aes-128-gcm -bytes 16 在我的机器上只需要 16ns ,这个测试的结果显然没有包含访问主内存的时间(已经在一级缓存上) 自创的加密算法安全不安全?这个问题有标准答案,不安全 在某个项目上是不是适用? 1 楼也已经答了,对没有价值的数据适用 有多大可能被破解?这个得给钱,不然不可能有高手帮你评估破解难度 |
58
tool2d 2023-10-09 12:52:15 +08:00
@julyclyde 你看我 20 楼的链接,“A perfect hash function is one that is collision-free.”,perfect 就代表了无碰撞。
当然这种 hash 都会限定输入的大小,一般都是输入多少位,输出就多少位。无限大小的输入,肯定有碰撞。 |
59
mightybruce 2023-10-09 13:02:46 +08:00 1
从你说出的进行简单的映射、移位、异 r 或、置换, 那么这个加密强度还不如 DES 。
AES 一轮加密就已经包含这些了,并比这个复杂,用到了非线性模块。 如果你遇到一个黑客专家或密码学高手,的确是很容易被破解, 你算法是建立在密码算法没人知晓的情况下, 参考二战的恩尼格玛密码机被破译,没有什么绝对安全的加密算法, 在密码学 Oracle 看来,时间和计算成本足够下都能破解。 如果有个人愿意花大价钱要搞你,你这个经不起推敲。我就不谈现代密码学分析如差分密码分析 另外题主说的不是 hash, 用密钥的对称加密。 |
60
xingguang 2023-10-09 13:41:18 +08:00 2
如果是自己项目,那么都可以,如果是公司项目,你这个算法导致出了问题那么你要背锅的,如果用市面上有的那么这个锅可以无限小
另外,其实感觉你不是寻求建议的,而是找认同的,看下来大部分都不太赞同你用自己写的算法,但是你的论点一直在于自己的快,市面上的太慢 |
61
wangxin13g 2023-10-09 14:49:40 +08:00
1.有没有一种可能,如果你用非整数方式存储用户 ID 会导致表变大?
2.有没有一种可能,有各种非规律自增 ID 工具,比如 snowflake ? |
62
xuanbg 2023-10-09 15:45:27 +08:00
想不明白 id 加密有什么用?只要够大且离散,一个个试的成本就足够高。就算给你试出来一个真实存在的 id ,你又能做什么呢?
|
63
ntedshen 2023-10-09 15:47:55 +08:00
https://github.com/Cyan4973/xxHash/wiki/Collision-ratio-comparison#collision-study
xxhash 有提供目前常见的一些 hash 方法的性能跑分,虽然说这里大多是非安全哈希,但是纯数字输入要都能碰撞我觉得不至于 low 到这个地步。。。 而且百万次 650ms 。。。兄你这专用算法好像还没达到通用算法的起跑线?。。。 解密倒是确实别想,老老实实彩虹表。。。 然后你这个 hashids 出的 base64 ,24 位长 18 位 binary ,144 位了。。。 嫌长和不好看的话,出 64 位 hex 就好,也就 16 位字符串。。。 |
64
xflcx1991 2023-10-09 15:55:32 +08:00
始终记住
1. 不要使用自己创建的加密算法。 2. 不要组合使用多个加密算法。 更多的见: 密码学常见应用错误: https://blog.csdn.net/u011130578/article/details/50435958 原文: https://security.stackexchange.com/questions/2202/lessons-learned-and-misconceptions-regarding-encryption-and-cryptology |
65
epicSoldier 2023-10-09 16:09:41 +08:00
@lithbitren 你数字 ID 我看就 13 位,用 hashid 完全可以生成 10 以内的字符串;不要设置生成 24 位的字符串
|
66
pkoukk 2023-10-09 16:18:14 +08:00
楼主啊,我是觉得你这一大长串数字一样没什么可读性而言啊
这么长,眼睛都看花了,念的时候错一位少一位很容易把 这个 ID 有什么地方需要可读么? 如果真的需要可读,为什么不加入字母呢,即使是 Base36(A-Z0-9)也比这个好读吧 |
67
zzNaLOGIC 2023-10-09 17:18:19 +08:00
同意楼上,ID 需要可读性的必要点在哪里。就算一串看似有规律的数字,真的会有人去读他么。
读完能得到什么呢 |
68
hyq 2023-10-09 18:39:06 +08:00
我觉得楼主的工作是有意义的。在特定场景下,自己设计一个映射去隐藏总用户数,这个需求肯定是存在的。
比如星巴克的点单上,就不会有单号,让人猜不到星巴克一天能卖几杯。但是麦当劳,瑞幸都有可读的单号,一下就能看到一天的销量。这种信息可以说属于商业机密,在有竞争的情况下,不能让对手知道自己的底牌。 |
69
hyq 2023-10-09 18:41:08 +08:00
用 hash 会有冲突的概率,用 aes 的结果是 128bit ,用 uuid 的结果更长。在作为数据库索引的时候需要考虑这个问题。
|
70
XiLingHost 2023-10-09 18:49:10 +08:00
id 这种东西为啥要人类可读?这玩意就不是给人看的啊,uuid 就足够了
你要给人看的应该是用户名或者昵称之类的 |
71
Terry166 2023-10-09 19:21:45 +08:00
之前做过两年 Web3 ,所以对密码学有一些研究,谈一下思路吧:
1 ,哈希算法:产生碰撞的几率取决于生成的哈希字符串的长度,一般是 256 位,因为分布均匀,产生碰撞的几率可以忽略不计,但是哈希算法是单向的,只能用于验证,无法从哈希值反推出原字符串,如果 op 需要反推出原来的字符串,哈希算法不符合要求 2 ,非对称加密算法:需要产生公私钥,给用户分发私钥,也不符合 3 ,对称加密:op 可以直接使用 AES 或者 DES ,自己持有密钥,把密文发送给用户,256 位的密钥就足够安全了,可以对抗量子计算机攻击:Symmetric encryption, or more specifically AES-256, is believed to be quantum-resistant. That means that quantum computers are not expected to be able to reduce the attack time enough to be effective if the key sizes are large enough. 参考: https://medium.com/bootdotdev/is-aes-256-quantum-resistant-4dc3447e7b82 ps:如果觉得密文太长,而且 id 总数不大,可以把密文生成一定长度的哈希值发送给用户(这种情况哈希算法产生碰撞的几率很小),后端保存哈希值和密文的 pair ,这样可以通过用户拿到的哈希值反推出原字符串。 |
72
Terry166 2023-10-09 20:43:17 +08:00
sorry ,为避免误导,对于非对称加密,修正一下,应该是给用户分发公钥和随机值,使用户能使用你的公钥传输密钥,用于后续通信
|
73
yankebupt 2023-10-09 21:57:55 +08:00
位数少的话可能会有人上显卡爆破,mutation 的数量随数字位数一起增长,如果不够会被全部塞进显存然后并行计算……
id13 位了,应该没人破 不知道初始 ID 的话穷举是个问题. 看到了上面差值 25 的问题。如果乘了某个数而不是你说的简单一一对应的变换,ID 数不是一一对应,爆破起来更难。 |
74
yankebupt 2023-10-09 22:02:05 +08:00
而且你是 1000 的映射表,只放 100 个 id 出来理论上是推不出你的映射表的……
|
75
Liftman 2023-10-09 22:26:41 +08:00
我从安全行业角度来看。你非要这样做的话,也没关系。爆破或者破解也不是关键,主要你需要测试是否存在横向越权。我改 id 的时候是否能访问到其他人的账户?。。。
|
76
xvIjicuCb 2023-10-10 01:36:35 +08:00
10000001?
|
77
comingnine 2023-10-10 01:50:56 +08:00
验证端是在服务器端的话,定期更换策略可行么
|
78
williamx 2023-10-10 08:04:44 +08:00
@lithbitren 如果是“加密出来的串太长,同样不具有可读性”,可以考虑先用标准算法加密,然后用自制算法做规格化。
|
79
lovelylain 2023-10-10 08:49:01 +08:00 via Android
自制加密算法,在破解价值不足够大时,没人会有兴趣去破解,安全的前提是你算法不泄漏,如果你算法泄漏甚至只是二进制泄漏,但密钥没泄漏,一般也较容易破解。建议改用标准加密算法再非标准进制转换,aes 结果是 128 位确实太长了,可以 des ,再非标准 base64 或 base36 转换一下。
|
80
cy18 2023-10-10 10:23:16 +08:00
你这属于重新做了一个方形的轮子...
|
81
spediacn 2023-10-10 19:46:05 +08:00 via iPhone
uuid 转为二进制存入数据库的性能可不差,多数人觉得他慢,主要是当文本来处理了,多了一些转换。
|
82
yhm2046 2023-10-14 20:44:23 +08:00
今天在图书馆找到那个网站了,可惜貌似关闭了: https://www.hackthissite.org/ ,最后的攻击记录是 2021 年 6 月 2 日
|