V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
这是一个专门讨论 idea 的地方。

每个人的时间,资源是有限的,有的时候你或许能够想到很多 idea,但是由于现实的限制,却并不是所有的 idea 都能够成为现实。

那这个时候,不妨可以把那些 idea 分享出来,启发别人。
chenjia404
V2EX  ›  奇思妙想

一个抗脱库的密码哈希方法

  •  
  •   chenjia404 · 291 天前 · 2143 次点击
    这是一个创建于 291 天前的主题,其中的信息可能已经有所发展或是发生改变。

    我之前做过一个方案: 哈希(用户名+密码+网站名)发送给服务器,服务器拿到提交的哈希和用户名,再哈希(用户名+密码+网站名+盐),把最后一步的哈希存在一张哈希表里面,下次用户登录的时候,只需要验证哈希表中是否有元素即可。 修改密码的时候修改用户的盐,写入新的哈希记录就行了,而且哈希表越来越大,每个网站的哈希表都不一样,泄露也没有办法跑彩虹表。 哈希函数只要是在 sha1 以上的,基本上冲突的可能性就很小。 这个方案也不需要提交明文密码到服务器,过安全测评也好过。

    28 条回复    2023-09-10 16:45:21 +08:00
    RatioPattern
        1
    RatioPattern  
       291 天前
    直接上感觉有问题,有没有大佬解析下
    dic
        2
    dic  
       291 天前
    直接 Bcrypt 就行了。
    dcsuibian
        3
    dcsuibian  
       291 天前 via Android
    修改密码的时候修改用户的盐是什么意思?盐不应该就一个么
    duke807
        4
    duke807  
       291 天前 via Android
    仅密码加网站名做 sha 运算和比对就行了
    用户名不需要
    这样不会有碰撞
    chenjia404
        5
    chenjia404  
    OP
       291 天前
    @dcsuibian #3 每个用户一个盐,修改密码的时候就更新盐。
    chenjia404
        6
    chenjia404  
    OP
       291 天前
    @duke807 #4 如果没有用户名,怎么确定这个哈希是这个用户呢?
    rekulas
        7
    rekulas  
       291 天前   ❤️ 2
    我看了半天,你这个所谓的方案跟正常加盐 hash 没有区别

    hash(用户名+密码+网站名+盐)
    hash(密码+盐)

    如果你觉得这两个安全性不一样的话只能说明你的盐有问题
    duke807
        8
    duke807  
       290 天前 via Android
    @chenjia404 用户名 明文 传输到服务器
    chenjia404
        9
    chenjia404  
    OP
       290 天前
    @rekulas #7 这个没有明文密码到服务器,以及不会被彩虹表破解,用户密码不会被反向破解出来。
    googlefans
        10
    googlefans  
       290 天前
    以后直接建内容站 直接静态
    不用数据库了
    lete
        11
    lete  
       290 天前
    了解一下: https://unpwd.github.io , 用户直接自己加密,就连你服务器都不知道我用户的明文密码
    lucybenz
        12
    lucybenz  
       290 天前
    说复杂了 简单讲就是做了密码字段客户端加密
    rekulas
        13
    rekulas  
       290 天前
    @chenjia404 其实前端传输密码 hash 早就普及开了,至于破解这个只要有足够安全的盐,你在里面再加入其它别的什么难度并没有提高或降低
    chenjia404
        14
    chenjia404  
    OP
       290 天前 via Android
    @rekulas 你没有看明白,这个方法,你没有办法反推用户密码
    dode
        15
    dode  
       290 天前 via Android
    现在有新接口了,客户端直接使用私钥验证信息,服务器端存储每个用户设备的公钥
    Leonkennedy2
        16
    Leonkennedy2  
       289 天前 via Android
    想法不错,多了一层“主观逻辑加密”
    patrickyoung
        17
    patrickyoung  
       289 天前 via iPhone
    @chenjia404 #14 并没有没有办法这一说,只是你主观安全而已,建议系统的重学密码学。整个方案就是普通的加盐 hash
    iX8NEGGn
        18
    iX8NEGGn  
       289 天前 via iPhone
    你这不就是把(用户名、网站名)当作盐而已嘛,还没有直接用随机的盐安全
    tt7
        19
    tt7  
       289 天前
    @chenjia404 #9 明文密码,和没有随机数的密码 hash 有什么区别吗?
    chenjia404
        20
    chenjia404  
    OP
       289 天前   ❤️ 1
    @patrickyoung #17 传统的加盐 hash ,保存了哈希和用户的对应关系,我这个没有保存用户和哈希对应关系。
    Liyuu
        21
    Liyuu  
       288 天前
    也就是说'网站名'可以换成任意一个常量,相当于加了一个没有存在库里的盐,这样吗?
    dallaslu
        22
    dallaslu  
       287 天前
    大概是这样吧?

    * 客户端计算 hash(user+pass+site),得出 user_hash
    * 注册时客户端将 user 和 user_hash 发送到服务器,服务器建立 user 并创建对应 salt ,计算 hash(user+user_hash+site+salt) 得出 auth_hash ,将其存入一个与 user 无关联的表中
    * 登录时服务器根据 user 查询 salt ,并计算 auth_hash ,如其在表中存在,则验证通过
    * 修改密码时,根据旧密码计算出旧的 auth_hash 并删除之,然后创建新 salt 并保存新 auth_hash

    被拖库时,攻击者只能看到 user 和对应 salt ,以及一堆无任何标识的 auth_hash ,既不能查表,也不能破解。

    上面各位提到网站名 site ,其实在做 auth_hash 时用 hash(user+user_hash+salt) 即可,site 在此没有必要。这个方案主要就两点,客户端不发真实密码、服务器不保存 auth_hash 与用户的关联。

    客户端发 hash 不发密码的出发点是什么呢?是怕被中间人嗅探、服务器日志记录吧,尽管保护了真实密码,但 user_hash 每次使用时都是不变的,在此网站也等同于密码,只起到有限的保护作用。

    服务器不存 auth_hash 与用户的关联,的确将拖库后的破解难度提升了用户数量的倍数,如果有十万用户,从 auth_hash 暴力破解指定用户的 pass ,最多需要计算 256^20*256^20*100000 次
    chenjia404
        23
    chenjia404  
    OP
       287 天前
    @dallaslu #22 旧的 auth_hash 不删除,这个表数据越多越好
    dallaslu
        24
    dallaslu  
       286 天前
    @chenjia404 即使这个策略奏效,也只是将 256^40 变成 256^43 ,「几乎不可能」乘以十万也是「几乎不可能」
    chenjia404
        25
    chenjia404  
    OP
       286 天前 via Android
    @dallaslu 恩,不过确实无法反向破解明文密码了,auth_hash 表公布都没有影响。
    stamhe
        26
    stamhe  
       234 天前
    @dode 嗨,想了解一下,你这个是你们项目有在使用的东西么?
    dode
        27
    dode  
       234 天前
    @stamhe 我们不涉及这个,我看到谷歌在用了
    stamhe
        28
    stamhe  
       233 天前
    @dode google 和 apple 他们接入的是 fido alliance 的 passkey 方案,这个方案是个残疾。不能用于工业应用。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   803 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 29ms · UTC 20:33 · PVG 04:33 · LAX 13:33 · JFK 16:33
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.