密码学得不好,请问这种简单用户 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]

7799 次点击
所在节点    信息安全
82 条回复
wangxin13g
2023-10-09 14:49:40 +08:00
1.有没有一种可能,如果你用非整数方式存储用户 ID 会导致表变大?
2.有没有一种可能,有各种非规律自增 ID 工具,比如 snowflake ?
xuanbg
2023-10-09 15:45:27 +08:00
想不明白 id 加密有什么用?只要够大且离散,一个个试的成本就足够高。就算给你试出来一个真实存在的 id ,你又能做什么呢?
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 位字符串。。。
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
Rainwater
2023-10-09 16:09:41 +08:00
@lithbitren 你数字 ID 我看就 13 位,用 hashid 完全可以生成 10 以内的字符串;不要设置生成 24 位的字符串
pkoukk
2023-10-09 16:18:14 +08:00
楼主啊,我是觉得你这一大长串数字一样没什么可读性而言啊
这么长,眼睛都看花了,念的时候错一位少一位很容易把
这个 ID 有什么地方需要可读么?
如果真的需要可读,为什么不加入字母呢,即使是 Base36(A-Z0-9)也比这个好读吧
zzNaLOGIC
2023-10-09 17:18:19 +08:00
同意楼上,ID 需要可读性的必要点在哪里。就算一串看似有规律的数字,真的会有人去读他么。
读完能得到什么呢
hyq
2023-10-09 18:39:06 +08:00
我觉得楼主的工作是有意义的。在特定场景下,自己设计一个映射去隐藏总用户数,这个需求肯定是存在的。
比如星巴克的点单上,就不会有单号,让人猜不到星巴克一天能卖几杯。但是麦当劳,瑞幸都有可读的单号,一下就能看到一天的销量。这种信息可以说属于商业机密,在有竞争的情况下,不能让对手知道自己的底牌。
hyq
2023-10-09 18:41:08 +08:00
用 hash 会有冲突的概率,用 aes 的结果是 128bit ,用 uuid 的结果更长。在作为数据库索引的时候需要考虑这个问题。
KagurazakaNyaa
2023-10-09 18:49:10 +08:00
id 这种东西为啥要人类可读?这玩意就不是给人看的啊,uuid 就足够了
你要给人看的应该是用户名或者昵称之类的
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 ,这样可以通过用户拿到的哈希值反推出原字符串。
Terry166
2023-10-09 20:43:17 +08:00
sorry ,为避免误导,对于非对称加密,修正一下,应该是给用户分发公钥和随机值,使用户能使用你的公钥传输密钥,用于后续通信
yankebupt
2023-10-09 21:57:55 +08:00
位数少的话可能会有人上显卡爆破,mutation 的数量随数字位数一起增长,如果不够会被全部塞进显存然后并行计算……
id13 位了,应该没人破
不知道初始 ID 的话穷举是个问题.
看到了上面差值 25 的问题。如果乘了某个数而不是你说的简单一一对应的变换,ID 数不是一一对应,爆破起来更难。
yankebupt
2023-10-09 22:02:05 +08:00
而且你是 1000 的映射表,只放 100 个 id 出来理论上是推不出你的映射表的……
Liftman
2023-10-09 22:26:41 +08:00
我从安全行业角度来看。你非要这样做的话,也没关系。爆破或者破解也不是关键,主要你需要测试是否存在横向越权。我改 id 的时候是否能访问到其他人的账户?。。。
xvIjicuCb
2023-10-10 01:36:35 +08:00
10000001?
comingnine
2023-10-10 01:50:56 +08:00
验证端是在服务器端的话,定期更换策略可行么
williamx
2023-10-10 08:04:44 +08:00
@lithbitren 如果是“加密出来的串太长,同样不具有可读性”,可以考虑先用标准算法加密,然后用自制算法做规格化。
lovelylain
2023-10-10 08:49:01 +08:00
自制加密算法,在破解价值不足够大时,没人会有兴趣去破解,安全的前提是你算法不泄漏,如果你算法泄漏甚至只是二进制泄漏,但密钥没泄漏,一般也较容易破解。建议改用标准加密算法再非标准进制转换,aes 结果是 128 位确实太长了,可以 des ,再非标准 base64 或 base36 转换一下。
cy18
2023-10-10 10:23:16 +08:00
你这属于重新做了一个方形的轮子...

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

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

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

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

© 2021 V2EX