V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
lithbitren
V2EX  ›  信息安全

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

  •  
  •   lithbitren · 2023-10-09 08:36:32 +08:00 · 6886 次点击
    这是一个创建于 402 天前的主题,其中的信息可能已经有所发展或是发生改变。

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

    82 条回复    2023-10-14 20:44:23 +08:00
    swulling
        1
    swulling  
       2023-10-09 08:39:19 +08:00 via iPhone   ❤️ 4
    你先自问下,有没有价值被别人破解。

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

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

    手动实现一个功能很有成就感,但是要是投入生产没有必要
    yhm2046
        9
    yhm2046  
       2023-10-09 09:16:35 +08:00   ❤️ 1
    《反黑客的艺术》一书里面提到有个公开所有人测试攻击的网站,暂时找不到,有兴趣可以放上去试试
    thorneLiu
        10
    thorneLiu  
       2023-10-09 09:16:53 +08:00 via Android
    加盐的 hash 就行了
    lithbitren
        11
    lithbitren  
    OP
       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
        12
    lithbitren  
    OP
       2023-10-09 09:23:00 +08:00
    @gps949 确实没考虑过随机 id ,以前学到的都要求尽可能顺序 id ,甚至+1id ,想想随机 id 也不是不行
    lithbitren
        13
    lithbitren  
    OP
       2023-10-09 09:28:15 +08:00
    @idealhs 所以不知道算法,理论上应该是非常难破解的对吧,所以说现代加密算法安全性的前提都是算法公开吗,我这个算法其实可以看成超简化的 DES 。
    MozzieW
        14
    MozzieW  
       2023-10-09 09:38:28 +08:00   ❤️ 2
    证明生成的 id 唯一了吗?比如 1 映射到 87654321 ,不会存在一个 K 也被映射到 87654321
    如 8 楼所说,现代密码学到基础是算法公开,保证密钥安全。你这个算法的安全其实是按算法保密(安全)保证的

    我猜测算法是把数字单个做处理,然后调整位置,第一个开头 813 ,第二个 876 ,后面出现了数字 813 接 876 ,应该出现循环规律了
    Tidusy
        15
    Tidusy  
       2023-10-09 09:39:49 +08:00
    为啥不直接用 AES 呢?性能应该也很好呀
    lithbitren
        16
    lithbitren  
    OP
       2023-10-09 09:48:14 +08:00
    @MozzieW 中间过程没有不可逆的过程,跑了一亿个数字 id ,也生成了一亿个密文 id ,没有重复的。循环规律没法证明不会出现,但在没有大样本对应的情况下,可能发现不了。
    codehz
        17
    codehz  
       2023-10-09 09:51:51 +08:00
    推荐用 UUIDv6 ,有序而且随机,128bit ,基本撞不到
    lithbitren
        18
    lithbitren  
    OP
       2023-10-09 09:52:24 +08:00
    @Tidusy 对照过 AES 和 DES ,取了里面的一些步骤进行简化写的,整个代码加密解密一起不过百行,性能当然比这两个号,同时安全性也不如这两个,但好在理论上加密过程可以不公开。一共不到百行的代码和密钥也差不多了,动态语言可以直接执行,静态语言就打包成二进制调用。
    Bay0net
        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 获取信息,那就没啥问题。
    tool2d
        20
    tool2d  
       2023-10-09 09:56:21 +08:00
    https://www.jandrewrogers.com/2019/02/12/fast-perfect-hashing/

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

    你自制算法没办法证明”无冲突“这点。
    lithbitren
        21
    lithbitren  
    OP
       2023-10-09 10:01:02 +08:00
    @Bay0net 对对对,原来是这样破的,虽然代码里面没有 25 ,但是 25 倍数确实会有规律,然后再做差指确实可以找出别的规律,如果随机递增 id 能进一步避免吗?
    xiangyuecn
        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)

    没啥意思,随手写一个简单无比的,别人都懒得去破解
    lithbitren
        23
    lithbitren  
    OP
       2023-10-09 10:05:22 +08:00
    @Bay0net 因为密文 id 也可以存成 64 位整数,性能比字符串好,所以应该会用密文 id 来作为索引获取一部分数据,起码不会在前端暴露原始 id 。
    c2const
        24
    c2const  
       2023-10-09 10:06:34 +08:00   ❤️ 2
    1.不是密码学专业的,就不要自己设计算法了,100%有漏洞,个人项目用就自己设计的就算了,公司项目最好直接用现成的算法 :(
    2.想哈希就老老实实用现成的哈希算法,加密就加密算法,现在对 AES 都有软件硬件的优化,速度不慢,想特殊点就用 Serpent 算法之类的 :)
    someday3
        25
    someday3  
       2023-10-09 10:32:14 +08:00
    密码学学完忘记的差不多了,但是记得老师每次上课都叮嘱过的一句。
    一定不要自己写密码算法,就用市面上现成的。
    tool2d
        26
    tool2d  
       2023-10-09 10:36:31 +08:00
    @lithbitren "但好在理论上加密过程可以不公开。"

    算法公开无所谓的,现在 HMAC 这种算法都是公开的,但是你没有密码,也没办法调用 HMAC ,把密码保管好就可以了。
    lithbitren
        27
    lithbitren  
    OP
       2023-10-09 10:38:34 +08:00
    市面上完整的加密算法不是不好,就是加密出来的串太长,同样不具有可读性,同样也没见过多少人真的拿用户 id 上 AES 的,甚至连 hashid 都少见,八股文里也就提提雪花、uuid ,偶尔见到有人来点大数异或、加减乘除,甚至纯纯递增也不少见,比如 B 站就用了很多年的递增 AV 号。
    lithbitren
        28
    lithbitren  
    OP
       2023-10-09 10:42:52 +08:00
    算法公开的前提是复杂度的证明原则上可以超过宇宙时间,我这个算法显然不能,成熟的算法各种操作都十几轮几十轮,我这个只有个位数轮次,如果能无限拿到明文 id ,破起来轻轻松松。
    kkwa56188
        29
    kkwa56188  
       2023-10-09 10:43:08 +08:00
    1. 自创的所谓"加密算法" 没有经过严格验证之前, 都可以直接认定是不安全的. 换句话说, 严格意义称得上"安全"的加密算法, 是白名单的. 你把白名单里的 AES 也好 DES 也好, 魔改了数学上就不等价了, 自然就又不白名单了
    2. 这个场景就是典型的加盐 hash 一下就完事了.
    zealotxxxx
        30
    zealotxxxx  
       2023-10-09 10:44:04 +08:00
    为什么一定要可读性呢? 可读就代表,要短,要有规律。你这不是显然给自己降低强度更容易破解么?
    tool2d
        31
    tool2d  
       2023-10-09 10:49:29 +08:00
    @lithbitren "算法公开的前提是复杂度的证明原则上可以超过宇宙时间"

    你没懂我的意思,算法公开的前提,是你算法要提供可设置密钥功能,比如可以自己换个加盐值。

    输入参数不能只有一个用户 ID ,还需要一个密钥,这样才可控。
    litchinn
        32
    litchinn  
       2023-10-09 10:51:50 +08:00
    > 简单的映射、移位、异或、置换
    这种方式和古典密码学一样,特征太明显了

    从需求出发,我觉得你的算法只要满足你现在的需求就能用,毕竟你又不给别人用

    从算法讨论出发
    1. 我觉得 1 楼说的对
    2. 永远不要自己设计使用加密算法
    3. 安全在于密钥而不在算法

    > 同样也没见过多少人真的拿用户 id 上 AES 的
    感觉就没多少场景有和你这个类似的需求的,通常来说 id 本来就不是什么敏感数据,暴露一个 id 和一个 hash 或加密后的 id 根本没多少区别,特别是现在大规模使用 uuid ,雪花 id 的情况下。
    担心伪造 id 应该通过数据权限控制,担心暴力刷接口应该用其他安全机制
    x1aoYao
        33
    x1aoYao  
       2023-10-09 10:54:36 +08:00
    晃眼一看,大致都是 8 或者 9 开头,太有规律性了,一点都不随机,加密至少要看起来像是噪声一样的随机内容。
    如果你只是想要生成 uuid ,有很多 hashid 算法,如果你是想加密可以直接用 AES 。

    如果有特殊需求,建议至少加盐再异或,至少看起来很随机(例如原文是 int64 ,然后随机一个 int64 作为盐,然后 hash 这个盐得到数去异或原文,再把盐拼在一起得到的 int128 用密钥来进行你的映射、移位、异或、置换这些。这样同样是可逆的,但至少看起来毫无规律了。)
    lithbitren
        34
    lithbitren  
    OP
       2023-10-09 10:58:14 +08:00
    @tool2d 是有密钥的啊,中间一些具体的参数是由密钥生成的,当然主要是算法太简单,有密钥应该也百分百会被破解。
    wupher
        35
    wupher  
       2023-10-09 11:00:27 +08:00
    hashids
    lithbitren
        36
    lithbitren  
    OP
       2023-10-09 11:01:07 +08:00
    @x1aoYao 首位是用来对齐的,实际只有 12 位,其实我的思路跟你的差不多,不过不知道要做到几个轮次才能看起来毫无规律。
    tool2d
        37
    tool2d  
       2023-10-09 11:08:25 +08:00
    @lithbitren "有密钥应该也百分百会被破解。"

    密钥换了,中间参数都换了,这也能破解?
    lithbitren
        38
    lithbitren  
    OP
       2023-10-09 11:08:35 +08:00
    @x1aoYao 简单来说,如果每个 id 只是末尾加一的话,除了映射,其他移位、异或、置换改变的数字及其顺序都是极为有限的,本来就很容易找出规律,成熟的加密算法分解来说也是这些个基本操作,但轮次会多很多,而且选取的固定参数可能有其特殊性(自创加密算法可能很难找到合适参数)。
    lithbitren
        39
    lithbitren  
    OP
       2023-10-09 11:12:24 +08:00
    @tool2d 首先有效数字就一共只有 13 位,如果能无限拿到具体对应的 id ,爆猜都能出结果,密钥没这么重要。
    cx9208
        40
    cx9208  
       2023-10-09 11:15:40 +08:00
    密码学里有一点就是不要自己发明加密算法。用户 id 可以用随机 id 或者 uuid 就够了
    tool2d
        41
    tool2d  
       2023-10-09 11:18:11 +08:00
    @lithbitren 这种算法都是放服务器上运行的,你多试几次就直接封 IP 了,怎么可能爆破。

    对任何加密算法来说,密钥都很重要。
    x1aoYao
        42
    x1aoYao  
       2023-10-09 11:20:48 +08:00   ❤️ 1
    @lithbitren 除去首位,楼上也有提到相邻差值很多 25 的。你如果不加盐,只是固定密钥的话,加异或移位的轮次效果很差。我提到把盐的 hash 得到的 int64 用来异或,就是为了密文除了与原文与密钥相关,还和一个随机数有关。而这个随机数是很难猜的,随机数的 hash 也足够随机。你解密的先得到盐,然后再 hash ,最后就可以得到原文了。
    最后即使原文再相近,得到密文和随机乱码差不多了。
    x1aoYao
        43
    x1aoYao  
       2023-10-09 11:26:25 +08:00   ❤️ 1
    @lithbitren 虽然随机数(盐)和它的 hash 实际有关联,但你后续还有简单的移位映射等,所以看起来就是一个 int128 随机数异或原文 int64(看起来) 当然 hash 函数要足够好(其实就是为了近似加密...
    sunmlight
        44
    sunmlight  
       2023-10-09 11:27:41 +08:00   ❤️ 1
    有现成的方案你不用, 非要自己搞些“小聪明”
    churchmice
        45
    churchmice  
       2023-10-09 11:28:26 +08:00
    闭门造轮子
    lithbitren
        46
    lithbitren  
    OP
       2023-10-09 11:33:55 +08:00
    @tool2d 不排除其用多个 ip 或者找到某个漏洞,在短时间内多次尝试,所以我主楼给出连续 100 个算是比较多了,其实正常来说应该拿不到这么多 id ,但就是这 100 个数据也被发现出规律,尽管要进一步确认规律也不是那么容易的。
    lithbitren
        47
    lithbitren  
    OP
       2023-10-09 11:37:22 +08:00
    @x1aoYao 不太容易,我用的映射表是 1000 对 1000 的,随机生成,由密钥做成的随机种子(各个过程中都有盐),但我发现主要问题还是+1 的情况下改变位数太少,这些个基本操作还得再重复很多次可能才能消除掉肉眼规律。
    chevalier
        48
    chevalier  
       2023-10-09 11:50:01 +08:00
    说个题外话,这种生成的 ID ,对数据库主键非常不友好,数据库写入压力会大很多
    lithbitren
        49
    lithbitren  
    OP
       2023-10-09 11:54:56 +08:00
    @chevalier 其实可以数据库主键递增,取出的时候计算出密文 id ,发送给前端的数据显示的是密文 id ,同时后端可以通过前端传回的密文 id 找到其他用户的真实主键 id ,全程全数字,压力比一些字符串 id 方案要小。
    virusdefender
        50
    virusdefender  
       2023-10-09 11:59:14 +08:00
    搞的太复杂了,没必要,用户表加个字段,保存另外一个随机 id 就好了。。。
    lithbitren
        51
    lithbitren  
    OP
       2023-10-09 12:01:41 +08:00
    随机 id 是可以考虑的,不过主流数据库随机 id 的存取性能显然也达不到秒内百万次。
    PVXLL
        52
    PVXLL  
       2023-10-09 12:02:33 +08:00 via iPhone
    民科就喜欢写这些东西,闭门造车的东西安全吗,一定不安全。这种东西还用担心性能,随便优化下 IO 操作时间就补回来了吧
    lithbitren
        53
    lithbitren  
    OP
       2023-10-09 12:11:38 +08:00
    一般对称加密算法对大数据块的加密性能比较好,但这种微型级别的数据的加密时间却也是毫秒级的,存取计算个用户名都要占用毫秒时间,太占用 cpu 了,不如不加密,也不如随机 id 。
    julyclyde
        54
    julyclyde  
       2023-10-09 12:28:01 +08:00
    hash 难道不是明显错误的答案吗?
    无数输入产生少量输出,有碰撞的啊!
    nothingistrue
        55
    nothingistrue  
       2023-10-09 12:32:52 +08:00
    自增用户 ID ,除了暴露用户量,还能暴露啥。如果它本来就是跟用户原本信息,注册时空信息都无关联,只是人工关联上去的一串数字,那么它的信息量就是个代号。这时候任何静态加密,都是画蛇添足而已,不论加密多少遍,它都可以直接拿出来当用户的代号。弄个雪花 ID 或者 HASH ,将其外围统计信息隐藏掉,并方便存储优化即可。

    你要真相搞隐藏用户 ID 的安全控制,那应该搞动态加密,即不同时空下的密文不同,还都能通过私钥推导到同一个 ID 。
    geelaw
        56
    geelaw  
       2023-10-09 12:35:55 +08:00 via iPhone
    要考虑算法是否安全,第一步是理解什么叫做“安全”,对于用户 ID 这种对象,我不了解是否有标准的安全定义,所以无法谈论安全性。
    CRVV
        57
    CRVV  
       2023-10-09 12:40:33 +08:00
    加密短的数据不可能耗时达到毫秒级
    openssl speed -evp aes-128-gcm -bytes 16
    在我的机器上只需要 16ns ,这个测试的结果显然没有包含访问主内存的时间(已经在一级缓存上)

    自创的加密算法安全不安全?这个问题有标准答案,不安全
    在某个项目上是不是适用? 1 楼也已经答了,对没有价值的数据适用
    有多大可能被破解?这个得给钱,不然不可能有高手帮你评估破解难度
    tool2d
        58
    tool2d  
       2023-10-09 12:52:15 +08:00
    @julyclyde 你看我 20 楼的链接,“A perfect hash function is one that is collision-free.”,perfect 就代表了无碰撞。

    当然这种 hash 都会限定输入的大小,一般都是输入多少位,输出就多少位。无限大小的输入,肯定有碰撞。
    mightybruce
        59
    mightybruce  
       2023-10-09 13:02:46 +08:00   ❤️ 1
    从你说出的进行简单的映射、移位、异 r 或、置换, 那么这个加密强度还不如 DES 。
    AES 一轮加密就已经包含这些了,并比这个复杂,用到了非线性模块。

    如果你遇到一个黑客专家或密码学高手,的确是很容易被破解, 你算法是建立在密码算法没人知晓的情况下,
    参考二战的恩尼格玛密码机被破译,没有什么绝对安全的加密算法, 在密码学 Oracle 看来,时间和计算成本足够下都能破解。
    如果有个人愿意花大价钱要搞你,你这个经不起推敲。我就不谈现代密码学分析如差分密码分析


    另外题主说的不是 hash, 用密钥的对称加密。
    xingguang
        60
    xingguang  
       2023-10-09 13:41:18 +08:00   ❤️ 2
    如果是自己项目,那么都可以,如果是公司项目,你这个算法导致出了问题那么你要背锅的,如果用市面上有的那么这个锅可以无限小
    另外,其实感觉你不是寻求建议的,而是找认同的,看下来大部分都不太赞同你用自己写的算法,但是你的论点一直在于自己的快,市面上的太慢
    wangxin13g
        61
    wangxin13g  
       2023-10-09 14:49:40 +08:00
    1.有没有一种可能,如果你用非整数方式存储用户 ID 会导致表变大?
    2.有没有一种可能,有各种非规律自增 ID 工具,比如 snowflake ?
    xuanbg
        62
    xuanbg  
       2023-10-09 15:45:27 +08:00
    想不明白 id 加密有什么用?只要够大且离散,一个个试的成本就足够高。就算给你试出来一个真实存在的 id ,你又能做什么呢?
    ntedshen
        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 位字符串。。。
    xflcx1991
        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
    epicSoldier
        65
    epicSoldier  
       2023-10-09 16:09:41 +08:00
    @lithbitren 你数字 ID 我看就 13 位,用 hashid 完全可以生成 10 以内的字符串;不要设置生成 24 位的字符串
    pkoukk
        66
    pkoukk  
       2023-10-09 16:18:14 +08:00
    楼主啊,我是觉得你这一大长串数字一样没什么可读性而言啊
    这么长,眼睛都看花了,念的时候错一位少一位很容易把
    这个 ID 有什么地方需要可读么?
    如果真的需要可读,为什么不加入字母呢,即使是 Base36(A-Z0-9)也比这个好读吧
    zzNaLOGIC
        67
    zzNaLOGIC  
       2023-10-09 17:18:19 +08:00
    同意楼上,ID 需要可读性的必要点在哪里。就算一串看似有规律的数字,真的会有人去读他么。
    读完能得到什么呢
    hyq
        68
    hyq  
       2023-10-09 18:39:06 +08:00
    我觉得楼主的工作是有意义的。在特定场景下,自己设计一个映射去隐藏总用户数,这个需求肯定是存在的。
    比如星巴克的点单上,就不会有单号,让人猜不到星巴克一天能卖几杯。但是麦当劳,瑞幸都有可读的单号,一下就能看到一天的销量。这种信息可以说属于商业机密,在有竞争的情况下,不能让对手知道自己的底牌。
    hyq
        69
    hyq  
       2023-10-09 18:41:08 +08:00
    用 hash 会有冲突的概率,用 aes 的结果是 128bit ,用 uuid 的结果更长。在作为数据库索引的时候需要考虑这个问题。
    XiLingHost
        70
    XiLingHost  
       2023-10-09 18:49:10 +08:00
    id 这种东西为啥要人类可读?这玩意就不是给人看的啊,uuid 就足够了
    你要给人看的应该是用户名或者昵称之类的
    Terry166
        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 ,这样可以通过用户拿到的哈希值反推出原字符串。
    Terry166
        72
    Terry166  
       2023-10-09 20:43:17 +08:00
    sorry ,为避免误导,对于非对称加密,修正一下,应该是给用户分发公钥和随机值,使用户能使用你的公钥传输密钥,用于后续通信
    yankebupt
        73
    yankebupt  
       2023-10-09 21:57:55 +08:00
    位数少的话可能会有人上显卡爆破,mutation 的数量随数字位数一起增长,如果不够会被全部塞进显存然后并行计算……
    id13 位了,应该没人破
    不知道初始 ID 的话穷举是个问题.
    看到了上面差值 25 的问题。如果乘了某个数而不是你说的简单一一对应的变换,ID 数不是一一对应,爆破起来更难。
    yankebupt
        74
    yankebupt  
       2023-10-09 22:02:05 +08:00
    而且你是 1000 的映射表,只放 100 个 id 出来理论上是推不出你的映射表的……
    Liftman
        75
    Liftman  
       2023-10-09 22:26:41 +08:00
    我从安全行业角度来看。你非要这样做的话,也没关系。爆破或者破解也不是关键,主要你需要测试是否存在横向越权。我改 id 的时候是否能访问到其他人的账户?。。。
    xvIjicuCb
        76
    xvIjicuCb  
       2023-10-10 01:36:35 +08:00
    10000001?
    comingnine
        77
    comingnine  
       2023-10-10 01:50:56 +08:00
    验证端是在服务器端的话,定期更换策略可行么
    williamx
        78
    williamx  
       2023-10-10 08:04:44 +08:00
    @lithbitren 如果是“加密出来的串太长,同样不具有可读性”,可以考虑先用标准算法加密,然后用自制算法做规格化。
    lovelylain
        79
    lovelylain  
       2023-10-10 08:49:01 +08:00 via Android
    自制加密算法,在破解价值不足够大时,没人会有兴趣去破解,安全的前提是你算法不泄漏,如果你算法泄漏甚至只是二进制泄漏,但密钥没泄漏,一般也较容易破解。建议改用标准加密算法再非标准进制转换,aes 结果是 128 位确实太长了,可以 des ,再非标准 base64 或 base36 转换一下。
    cy18
        80
    cy18  
       2023-10-10 10:23:16 +08:00
    你这属于重新做了一个方形的轮子...
    spediacn
        81
    spediacn  
       2023-10-10 19:46:05 +08:00 via iPhone
    uuid 转为二进制存入数据库的性能可不差,多数人觉得他慢,主要是当文本来处理了,多了一些转换。
    yhm2046
        82
    yhm2046  
       2023-10-14 20:44:23 +08:00
    今天在图书馆找到那个网站了,可惜貌似关闭了: https://www.hackthissite.org/ ,最后的攻击记录是 2021 年 6 月 2 日
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2400 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 31ms · UTC 00:02 · PVG 08:02 · LAX 16:02 · JFK 19:02
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.