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

活动分享码直接使用 snowflake 生成的 ID 是否存在什么安全隐患?

  •  
  •   kid1412621 · 2019-09-12 13:24:09 +08:00 via Android · 5694 次点击
    这是一个创建于 1924 天前的主题,其中的信息可能已经有所发展或是发生改变。

    分享码和用户绑定,唯一且固定,无其它额外需求。

    28 条回复    2019-09-18 17:40:26 +08:00
    momocraft
        1
    momocraft  
       2019-09-12 13:54:44 +08:00
    snowflake 的设计目的是短且(无恶意使用时)避免碰撞。

    如果被枚举也没关系就没关系,否则可能 hash/uuid4 好一些。
    kid1412621
        2
    kid1412621  
    OP
       2019-09-12 14:10:02 +08:00
    @momocraft 谢谢, 但为什么会好些呢? uuid4 我看是降低碰撞, snowflake 应该是能完全避免碰撞吧(1s 内多少次)
    IamNotShady
        3
    IamNotShady  
       2019-09-12 14:13:34 +08:00
    维护好机器 ID 和数据中心 ID 一般没问题
    kid1412621
        4
    kid1412621  
    OP
       2019-09-12 14:15:05 +08:00
    @momocraft 有点懂了,是否是因为 snowflake 的生成是可预测的呢?就有可能被枚举来使用
    kid1412621
        5
    kid1412621  
    OP
       2019-09-12 14:16:36 +08:00
    @IamNotShady 嗯, 如果这个 id 同时是用户在系统中的唯一标识, 会有什么设计上的缺陷吗?
    Mithril
        6
    Mithril  
       2019-09-12 14:20:48 +08:00
    @kid1412621 最好不要暴露这个 ID,会有安全隐患。这个值可以被猜到,也可以自己计算出来一个可能不存在的 ID。如果你其他地方没有全部做好验证,那就可能给你插进来几条错误数据。
    直接随机对称加密一下就好了。
    IamNotShady
        7
    IamNotShady  
       2019-09-12 14:21:07 +08:00
    @kid1412621 一楼说的对 我没认真审题 这种需求场景不适合用 snowflake hash/uuid4 是更好的选择
    kid1412621
        8
    kid1412621  
    OP
       2019-09-12 14:32:50 +08:00
    @Mithril 嗯, 但为什么要对称加密呢? secure hash 呢?
    kid1412621
        9
    kid1412621  
    OP
       2019-09-12 14:43:02 +08:00
    @IamNotShady @momocraft
    再谢, 但 uuid 有些过长了, 有什么好的方式变短些并保证唯一性吗?
    ryV60s
        10
    ryV60s  
       2019-09-12 15:19:56 +08:00
    hashids 是否符合需求。
    LeeSeoung
        11
    LeeSeoung  
       2019-09-12 15:50:58 +08:00
    可以看下 zfb 订单号
    IamNotShady
        12
    IamNotShady  
       2019-09-12 15:51:47 +08:00
    @kid1412621 UUID 可以指定长度的
    kid1412621
        13
    kid1412621  
    OP
       2019-09-12 16:02:52 +08:00
    @ryV60s 看来下感觉不错, 我看文档说不用每次存 db, 通过每次加解密, 想问下你们项目使用也是类似需求吗? 是这么处理的
    kid1412621
        14
    kid1412621  
    OP
       2019-09-12 16:05:17 +08:00
    @LeeSeoung 那个感觉不太符合这场景, 而且也没必要过度设计
    ryV60s
        15
    ryV60s  
       2019-09-12 16:09:12 +08:00
    @kid1412621 #13 对啊 逻辑层面加密解密的,跟 db 没关系的。前端 id 都是用这个,防止爬虫遍历。
    kid1412621
        16
    kid1412621  
    OP
       2019-09-12 16:20:52 +08:00
    @IamNotShady 咦, 这倒第一次听说, uuid 不是规范吗? 这么指定长度呢? 不是截取吧?
    kid1412621
        17
    kid1412621  
    OP
       2019-09-12 16:24:13 +08:00
    @ryV60s 只是 id 用吗? 我这里需求是分享码呀,要在个人信息中返回, 不会每次返回都算一遍吧(不考虑缓存的话)
    ryV60s
        18
    ryV60s  
       2019-09-12 16:36:54 +08:00
    @kid1412621 #17 你们这需求简单点的话,直接用用户数据库 id 直接加密当分享码,前端传过来再解密就是用户数据库 id,至于具体逻辑看你们需求了。

    我们是后端输出 id 给前端统一加密,前端传 id 过来后端统一处理解密,暂时是每个涉及 id 的接口都得处理加密解密。
    当然需要不需要解密加密,缓存得看具体逻辑了。
    IamNotShady
        19
    IamNotShady  
       2019-09-12 16:46:18 +08:00
    IamNotShady
        20
    IamNotShady  
       2019-09-12 16:50:35 +08:00
    @kid1412621 如果你用 base62 可以压的更短
    IamNotShady
        21
    IamNotShady  
       2019-09-12 16:52:09 +08:00
    momocraft
        22
    momocraft  
       2019-09-12 17:04:23 +08:00
    要绝对唯一往往就需要生成算法是决定性 (提前生成好也是一种决定性)。再要短就容易被枚举。

    几十个 bit 足够在在现实的概率上唯一了,比如 https://alex7kom.github.io/nano-nanoid-cc/
    sun522198558
        23
    sun522198558  
       2019-09-12 17:07:51 +08:00
    短网址那种做法
    不想自己做短网址服务,可以自己每个用户的 url 去短网址服务申请一个短网址取短网址的最后几位存入自己的数据库
    偷懒做法
    zhenjiachen
        24
    zhenjiachen  
       2019-09-12 22:55:09 +08:00 via iPhone
    我是直接把用户 ID 和活动 ID 拼接,然后中间家几个分隔符,再 md5
    然后把 md5 的值和用户 id 还有活动 ID 存数据库。
    troywinter
        25
    troywinter  
       2019-09-13 00:19:37 +08:00
    没必要过度设计,snowflake 已经是相当广泛应用过的 id 生成算法,碰撞不用考虑,对外暴露 id 加 salt 加密就可以了,只要不把原始 id 暴露出来就可以,等有人攻击你们系统了,也就有钱搞这些了
    kid1412621
        26
    kid1412621  
    OP
       2019-09-18 17:38:33 +08:00
    @troywinter 感谢分享,我觉得我的问题应该变成暴露用户 id 是否有隐患。

    根据这里( https://stackoverflow.com/questions/3629134/should-i-expose-a-user-id-to-public ),一般应用直接暴露 id 应该没事,我看好多网站也是暴露了的。当然具体情况具体分析,我这里的需求可能不能直接暴露,因为 id 和兑换码联系了起来,要防止被枚举。
    我的想法是这样,还是简单些做,用户注册的时候用 snowflake 生成的 id 做一遍 hash 或 encode,这样至少不是直接暴露 id,然后存到 db 做个 index, 兑换时(用户的分享码就是别人的兑换码,需求是这样 = =)再用这个码去找是否存在。
    不知这样妥否,有无可以优化的地方。
    kid1412621
        27
    kid1412621  
    OP
       2019-09-18 17:39:44 +08:00
    @IamNotShady 有点疑问,我在线( http://encode-base62.nichabi.com )转了下,发现和这个库的结果不一样呢
    kid1412621
        28
    kid1412621  
    OP
       2019-09-18 17:40:26 +08:00
    @zhenjiachen 同意,简单直接,不过我这需求有些不一样
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1018 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 21:05 · PVG 05:05 · LAX 13:05 · JFK 16:05
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.