V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
whileFalse
V2EX  ›  问与答

目前有没有用密码登录的网站做了前端加盐加密?

  •  
  •   whileFalse · 2018-12-29 13:30:56 +08:00 · 4752 次点击
    这是一个创建于 2152 天前的主题,其中的信息可能已经有所发展或是发生改变。

    后端再次加盐加密。确保服务无法拿到用户明文密码。

    第 1 条附言  ·  2018-12-29 16:09:24 +08:00
    客户端非对称加密只能保证传输过程密码不泄露。
    服务端加盐加密只能保证密码无法从数据库层面泄露。

    但服务端程序猿还是可以拿到用户密码明文,也即只要网站想要,就可以用用户密码去别的网站撞库。
    我想保证的是,只要客户端代码安全,服务端就拿不到用户密码明文。
    31 条回复    2018-12-30 15:04:33 +08:00
    GDC
        1
    GDC  
       2018-12-29 13:40:42 +08:00 via iPhone
    有,最初的目的是为了防止中间人抓包,在 https 没普及的时候还是有点用的
    Mogugugugu
        2
    Mogugugugu  
       2018-12-29 15:17:07 +08:00
    有,刚做完,前端加密,后端再加密- -
    helone
        3
    helone  
       2018-12-29 15:21:55 +08:00
    现在也很有用,即使你上了 https,正如楼主说的确保服务无法拿到用户明文密码

    我记得 twitter 就爆出过这种事情,虽然数据中没有记录明文密码,但是日志里记录了用户的明文密码(我猜测可能是用户请求的日志,日志中有用户的请求明文数据),解决方案很简单,前端加密后,后端服务再次加密后与数据中的值校验,无论是哪一步都保证了用户密码得保密性
    TomatoYuyuko
        4
    TomatoYuyuko  
       2018-12-29 15:23:05 +08:00
    非对称加密√
    yunye
        5
    yunye  
       2018-12-29 15:26:33 +08:00
    用 RSA 加密实现 Web 登录密码加密传输 - guogangj - 博客园
    https://www.cnblogs.com/guogangj/archive/2012/03/05/2381117.html
    WindProtect
        6
    WindProtect  
       2018-12-29 15:41:05 +08:00
    前端加盐的意义何在?如果是怕传输过程被撸的话,https + 前端加密就行了吧,加盐的话需要先获取账号的盐然后再加盐再加密,这样就已经多了一步交互了,即使这样就算传输过程中被撸了,破解的人也可以直接用了加盐加密的密码直接提交登录了吧。再换个思路,就算你盐是前端生成的,然后还是得把盐和最终加密密码一起提交了,过程中被撸了,那黑客拿着盐和最终密码再次提交也照样登录吧。
    nfroot
        7
    nfroot  
       2018-12-29 15:56:53 +08:00
    @WindProtect 当前时间(服务器判断时间差异比如超过 2 分钟就直接拒绝)+随机值(服务器判断随机值不能重复使用)+用户名+密码
    生成 hash,拿着盐也不许再提交,服务器验证一下随机值和时间搭配只能用一次。
    nfroot
        8
    nfroot  
       2018-12-29 15:57:56 +08:00
    接楼上,再加一个 IP 也判断

    @WindProtect 其实做这些都没用,服务器不判断 IP 的话,直接拿到你登录后的 cookie 就好了。
    whileFalse
        9
    whileFalse  
    OP
       2018-12-29 16:03:04 +08:00
    @WindProtect 君不见好多服务(比如 google )都是让你先输入用户名,然后密码框才出现么。这个时候就够从服务器拉盐了。
    还有,读题,你就明白为啥要前端加盐加密了。
    allenhu
        10
    allenhu  
       2018-12-29 16:20:27 +08:00 via Android
    没太大意义,明文还是密文,一般都是后端定
    isayme
        11
    isayme  
       2018-12-29 16:23:14 +08:00
    网易 126/163 邮箱 好像在用
    solaro
        12
    solaro  
       2018-12-29 16:26:11 +08:00
    前端加密有意义吗?
    zpf124
        13
    zpf124  
       2018-12-29 16:27:37 +08:00
    你不用加盐, 直接用复杂一点的摘要算法(比如 sha256) 后端就还原不出来密码明文了。

    前端加盐 存在哪?
    cookie ? 用户换个浏览器得重新找回密码一次?
    js 里写死? 那找到你这个盐值也不难,而且加密用同一个盐值和不加盐差距不大...
    whileFalse
        14
    whileFalse  
    OP
       2018-12-29 16:35:04 +08:00
    @zpf124 然后后端彩虹表一下。后端加盐的意义,套在前端哪里不难理解吧。
    盐依然存数据库,可以和后端的盐共享,登录时输入用户名后拿着用户名管后端要。
    或者拿用户名做盐也行。
    WindProtect
        15
    WindProtect  
       2018-12-29 16:42:59 +08:00
    @nfroot 其实那时间那个方案我想过,只是你提交的时候也得提交时间和随机值,不然直接给服务器服务器也不知道是什么时候做的加密无法吧时间加进去校验,这样的话是能提高攻击成本但针对性的攻击也是很好破解的。ip 也是,同个局域网就好破。

    另外,我原本是想讨论为啥前端需要加盐而已,加密手法其实只是增加破解难度而不能防止人家破解密码,所以我觉得 @whileFalse 补充说的防撞库这个观点确实可以说服我在前端加盐。
    springGun
        16
    springGun  
       2018-12-29 16:49:41 +08:00
    在使用了 https 后前端加密的意义何在?
    nfroot
        17
    nfroot  
       2018-12-29 16:54:23 +08:00
    @WindProtect 安全措施从来就没有一本万利的事情,都是一项项安全措施叠加起来形成一个很高的程度。并不能因为它的作用小,就放弃。

    就像备份数据,很可能在比较好的环境下,实时备份、定时备份、离线备份、检测备份进行了十年,但是却毫无作用(根本就没出事故用到备份),那这一切就没意义就不要做了吗?

    我们不要出了事情再去检查,为什么那个东西机制那么简单你却没有做?多做一个措施到底是有多害人,害到旁人?为什么一堆人总是说,这个没用,那个没用。不要搞,没意义?


    回到主题,HTTPS 理论上是不能被劫持的,但是特殊情况下,比如企业、病毒内置了根证书,不就可以侦听明文了?可能有人又要说。有侦听就有劫持篡改的能力,干脆直接做个假的输入框,直接获取真实密码。

    真的不是这样的,不是所有人都能做到最厉害的那一步的,每一步都是一个门槛,所以要一步步去做措施尽可能的避免。
    WindProtect
        18
    WindProtect  
       2018-12-29 17:20:19 +08:00
    @nfroot 对的,您教训的是。
    Vegetable
        19
    Vegetable  
       2018-12-29 17:26:07 +08:00
    前端只能不可逆加密,比如哈希,才能防止后端拿到明文.加盐没什么必要了吧,前端加盐等于没加.
    bestie
        20
    bestie  
       2018-12-29 17:30:07 +08:00
    @springGun 应该是防内鬼之类的吧,或者是防止 access log 被拖
    t6attack
        21
    t6attack  
       2018-12-29 17:42:36 +08:00
    明白 LZ 的意思。明文密码 /可逆加密密码 不发往服务端。从根本上杜绝网线之外的人拿到用户明文密码。
    作为用户,我当然希望这样。作为网站方,我不会这么干。
    geelaw
        22
    geelaw  
       2018-12-29 17:45:31 +08:00
    @whileFalse #0 防止服务拿到密码,我看不出来意义何在。如果你相信前端的代码,则你可以信任这个公司不会偷你的密码;如果你不相信但又不得不用,使用一个随机密码。

    @helone #3 这个解决方案是错误的。

    @nfroot #17 对于病毒,我想是可以做绝的;对于企业,答案是不要在你公司控制的网络下使用个人账户。没有用就是没有用,不要给自己安全的假象。

    前端加盐的结果是,用户实质上的密码变成了加盐结果,而不是用户输入的东西(攻击者可以直接发送加盐之后的结果)。
    前端加密属于多此一举,这是用 HTTPS 做的。此外,好的实践是后端拿到密码之后验证身份,然后把身份信息从 用户名+密码 变成后端代码认可的不含密码的对象(标识符等),而不是继续携带密码传入更深的业务逻辑(楼主所说的“服务”)。

    这类似于登录 Windows 之后,程序使用用户的 token 而不是用户的 用户名+密码,因为程序的环境受 Windows Local Security Authority 的管辖,只需要相信 LSA 即可——具体业务逻辑受后端控制器的管辖,只需要相信控制器的身份验证部分决定的结果即可。
    whileFalse
        23
    whileFalse  
    OP
       2018-12-29 17:54:01 +08:00
    @geelaw 从公司层面,可以装个 X 顺便防止内鬼或像 Github 那样的失误。

    你知道有数字货币交易所拿自己用户的密码去别的交易所撞库吗?虽然这手可能不是内鬼,而是高层干的
    maichael
        24
    maichael  
       2018-12-29 17:56:25 +08:00
    @nfroot #17 但问题是每一项的安全措施都不是没有代价的。
    whileFalse
        25
    whileFalse  
    OP
       2018-12-29 18:22:52 +08:00
    @maichael 这个措施的代价高吗?

    对于前后端程序来说,两小时够不够?
    对于用户来说,如果用户先输入用户名,再输入密码,则用户体验不会有任何损失。如果用户使用密码填充软件,会多等一个请求,0.2 秒吧。
    zpf124
        26
    zpf124  
       2018-12-29 20:34:04 +08:00
    @whileFalse 所以采用 sha256 或者更高级的摘要算法不就好了。
    后端既然能知道盐,那自然也可以找加盐的彩虹表啊。


    而且后端向前端发盐值,那这个盐和没加一样。
    后端推荐加密 带 盐值,同时也建议不要使用统一盐,为的就是不让别人知道具体的盐值是什么,你盐都发给前端了,那加盐的更没意义。
    whileFalse
        27
    whileFalse  
    OP
       2018-12-29 21:03:26 +08:00
    @zpf124 建议去研究下盐的本质。盐本来就是可公开的。不使用统一盐的唯一目的是为了防止有人为了特定的盐作出彩虹表。就是说,防止被团灭。只要每个人的盐不一样,盐就起到了作用。

    为了防止后端发来的盐是一个已经打了彩虹表的盐,那么可以这么做:盐是一个包含用户名自身的字符串。这样前端可以证明盐是足够复杂的。
    MonoLogueChi
        28
    MonoLogueChi  
       2018-12-29 23:19:20 +08:00 via Android
    可能有意义吧,我以前搞个一个前端加盐加密再截取传输到后端,然后后端再加盐加密严重,个人感觉是不太可能用彩虹表逆推出来,即使从数据库里可以逆推到前端传输过来的数据,但是前端传输过来的数据已经是被截取过的,用被截取的数据去推完整的数据应该不太可能吧。

    关于加密这方面我一点都不懂,根据个人臆想来做的
    nfroot
        29
    nfroot  
       2018-12-30 12:13:30 +08:00 via Android
    @geelaw 对于你说的"攻击者可以直接发送加盐之后的结果"认真看内容啊,你没理解就自己设计破解方法了,太长我就简化下,你确定坏人能拿到我的数据重新提交?你随便提交,验证成功算我输!


    服务器开启 https

    post 下面几个数据给服务器
    用户名
    当前时间
    随机值
    sha256(用户名+sha256(密码)+当前时间+随机值)

    服务器
    判断客户端发来的时间是 60 秒以内
    判断随机值不是在 60 秒或者更长时间内使用过
    以上两个条件通过后,进行和客户端一样的计算,如果服务器存储时加盐了,客户端发送前要获取盐值

    对比两个值是否一致,一致便通过,在 session 变量记录客户端 IP。每次客户端执行动作的时候判断 IP 是否一致。session 要有过期机制。


    如果客户端提交的数据被再次提交,你试试能不能通过服务器的检查!不能吧?

    只有两种可能破解
    1.session 失效前另一个局域网的电脑偷取 cookie。和 UA 之类的浏览器标志,代替用户操作。
    2.手段达到能随意修改用户页面,这个就不用讨论了。

    同样还有更好的办法,比如
    二次验证。
    前端只提交用户名,提交后服务器将验证码发邮件或短信或微信通知用户,用户输入验证码完成登陆
    客户端插件、软件防护
    客户端插件简单的可以由浏览器插件实现,也可以用应用程序实现,用插件去预先获得一个客户端 ID 和密码(用来标识客户端),使用插件完成计算过程。使用客户端密码去计算用户信息比如 sha256 或者自己的加密算法并完成登录。软件防护就是监控这个网址的代码是不是被修改了。

    这应该是市面上可以实现的绝大部分方法了。

    但是这仍然不是绝对安全的,应用程序和操作系统都是可以逆向的。




    至于"不要在你公司控制的网络下使用个人账户",这个只是说说而已,我们在给用户培训时说了一千遍一万遍,你觉得他们会听吗?密码 123456 的还少吗?所以我认为我们只能尽可能一步步去完善安全措施,降低用户出现损失的可能。


    但是基于条件限制,我们不可能做到所有,所以我上面的回答也仅仅是因为很多人觉得没有意义,连程序员都觉得没有意义,用户又会在意什么呢? 123456,abc123,Abc123,当然是怎么简单怎么来。。
    nfroot
        30
    nfroot  
       2018-12-30 12:36:15 +08:00 via Android
    其实越想越和大公司差不多了,大公司能力强,会加入更多的因素,但是我认为还是有必要在能做到的条件下做到极致,反正这个东西一次设计能用很久的。


    注重安全不是什么坏事啊。
    geelaw
        31
    geelaw  
       2018-12-30 15:04:33 +08:00
    @nfroot #29 之前没有针对 #7 回复。你在 #7 的设计不能被总结为“加盐”,而是一种 TOTP。此外,无论怎样做都需要在设置密码的时候传输密码。

    > 我们在给用户培训时说了一千遍一万遍,你觉得他们会听吗?

    技术不能用来解决人的脆弱。

    Minor pick:
    > 只有两种可能破解
    话不要说太满,请使用形式化的方式论证。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1035 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 30ms · UTC 22:24 · PVG 06:24 · LAX 14:24 · JFK 17:24
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.