密码学得不好,请问这种简单用户 id 加密模式的安全性有多大问题?

2023-10-09 08:36:32 +08:00
 lithbitren

真实用户 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]

6906 次点击
所在节点    信息安全
82 条回复
swulling
2023-10-09 08:39:19 +08:00
你先自问下,有没有价值被别人破解。

如果没有价值,那安全性非常高。
lithbitren
2023-10-09 08:43:15 +08:00
@swulling 用户 id 这种东西,说有价值也算有价值,但暴露了问题也不大。就像 B 站的 BV 号,也算有价值,不过很快也被破解了。也不知道大佬是怎么破解的,就算知道部分视频对应的 AV 号,竟然连具体算法都可以写出来,除了内部泄露真的能做到吗。
swulling
2023-10-09 08:46:32 +08:00
@lithbitren 也要看体量。

所以 B 站那个体量那就是有价值的,你或者我多数人的体量那就是无价值的,甚至可能用递增 id 也没啥问题。
imnpc
2023-10-09 08:52:11 +08:00
搜索下 hashid ,都有解决方案了
xtreme1
2023-10-09 08:52:36 +08:00
100 个密文很难分析有没有消除统计学特征啊, 你还不如直接把算法放上来
算法公开只有密钥需要保密, 这个是现代密码的基本要求
idealhs
2023-10-09 08:57:22 +08:00
你这个黑盒肯定会难以破解吧,又不知道算法。
不过 4 楼说的对,一般用 hashid 别手搓
gps949
2023-10-09 09:02:07 +08:00
个人观点:
1 、任何自制密码算法都可以认为未经对其安全性的广泛验证,基本可以认为是不安全的。
(注:这种不安全是理论上的,有些人一说什么不安全就挑衅人去破解,前些天 v2 上有个搞前端加密的就这样)
2 、理论上应该把 ID 设置成低业务价值的。如果认为 ID 存在价值,首先就不该连续,甚至不应该包含时间戳或者顺序信息。这种情况可以考虑生成随机 ID ,或者非随机 ID 做 hash 。加密的话造成的不必要算法复杂度和性能损耗大于必要性。
zhanggg
2023-10-09 09:09:23 +08:00
你这诉求明显答案就是 hash

手动实现一个功能很有成就感,但是要是投入生产没有必要
yhm2046
2023-10-09 09:16:35 +08:00
《反黑客的艺术》一书里面提到有个公开所有人测试攻击的网站,暂时找不到,有兴趣可以放上去试试
thorneLiu
2023-10-09 09:16:53 +08:00
加盐的 hash 就行了
lithbitren
2023-10-09 09:18:01 +08:00
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"]

太长了,而且性能只有我这个自制算法的十分之一这样。。
当然,安全性肯定好过我这个,至于加密过程过于简单,当然是尽可能不公开代码。
lithbitren
2023-10-09 09:23:00 +08:00
@gps949 确实没考虑过随机 id ,以前学到的都要求尽可能顺序 id ,甚至+1id ,想想随机 id 也不是不行
lithbitren
2023-10-09 09:28:15 +08:00
@idealhs 所以不知道算法,理论上应该是非常难破解的对吧,所以说现代加密算法安全性的前提都是算法公开吗,我这个算法其实可以看成超简化的 DES 。
MozzieW
2023-10-09 09:38:28 +08:00
证明生成的 id 唯一了吗?比如 1 映射到 87654321 ,不会存在一个 K 也被映射到 87654321
如 8 楼所说,现代密码学到基础是算法公开,保证密钥安全。你这个算法的安全其实是按算法保密(安全)保证的

我猜测算法是把数字单个做处理,然后调整位置,第一个开头 813 ,第二个 876 ,后面出现了数字 813 接 876 ,应该出现循环规律了
Tidusy
2023-10-09 09:39:49 +08:00
为啥不直接用 AES 呢?性能应该也很好呀
lithbitren
2023-10-09 09:48:14 +08:00
@MozzieW 中间过程没有不可逆的过程,跑了一亿个数字 id ,也生成了一亿个密文 id ,没有重复的。循环规律没法证明不会出现,但在没有大样本对应的情况下,可能发现不了。
codehz
2023-10-09 09:51:51 +08:00
推荐用 UUIDv6 ,有序而且随机,128bit ,基本撞不到
lithbitren
2023-10-09 09:52:24 +08:00
@Tidusy 对照过 AES 和 DES ,取了里面的一些步骤进行简化写的,整个代码加密解密一起不过百行,性能当然比这两个号,同时安全性也不如这两个,但好在理论上加密过程可以不公开。一共不到百行的代码和密钥也差不多了,动态语言可以直接执行,静态语言就打包成二进制调用。
Bay0net
2023-10-09 09:54:40 +08:00
如果需要反推算法的话,需要你把 [连续的 100 个 id] 的明文也发出来,因为攻击者是能获取这个信息的。

如果 OP 只通过 ID 去获取信息,不判断 Cookie 的话,这个算法肯定是有问题的。

把密文排序一下,很多相邻的密文差值都是 25 ,比如下面这几组

8034436934565
8034436934590

8035090949285
8035090949310

8038067215397
8038067215422

8060335193637
8060335193662

8060407228965
8060407228990

8062245008293
8062245008318

爆破的话直接跑 25 倍数就行了,并不需要反推 ID ,就能获取到其他用户的信息了。

如果做了鉴权,别有接口直接通过密文 ID 获取信息,那就没啥问题。
tool2d
2023-10-09 09:56:21 +08:00
https://www.jandrewrogers.com/2019/02/12/fast-perfect-hashing/

aes 速度很快的,可以做到完美无冲突。

你自制算法没办法证明”无冲突“这点。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/980076

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX