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

关于前后端密码传输与存储?

  •  
  •   daguaochengtang · 2021-07-14 08:45:14 +08:00 · 6887 次点击
    这是一个创建于 1230 天前的主题,其中的信息可能已经有所发展或是发生改变。
    登录时,前端调用接口传的密码参数(加密,不加密),以及后端存储密码(加密,不加密)。你们是怎么做的?
    排列组合有 4 种:
    1. 前端加密,后端加密
    2. 前端加密,后端不加密
    3. 前端不加密,后端加密
    4. 前端不加密,后端不加密
    我们目前采用的是第 1 种,用户传输加密后的密码直接和库里加密后的密码比对。但是我偶然听闻了之前 csdn 发生过用户密码大量泄漏的事件。就想到其实前后端都加密的话,如果数据库密码泄露,不就能直接调接口了吗?
    所以我想,是不是第 3 种要安全一点,前端传输名文,服务端拿到名文密码后,加密后与库里密码比对。这样即使数据库密码泄露,也无法得知密码名文,就无法调接口了。
    当然,我知道,如果数据库都泄露了,光凭这一点已经无法谈及安全问题了。只是想就事论事,想知道你们是怎么做的,这个是否有业内约定俗成的标准?
    51 条回复    2021-07-15 04:19:59 +08:00
    marcomarco
        1
    marcomarco  
       2021-07-14 08:53:49 +08:00 via iPhone
    我们一般是 3,然后传输过程加密,让人拦截不到传输内容。
    marcomarco
        2
    marcomarco  
       2021-07-14 08:55:29 +08:00 via iPhone   ❤️ 1
    @marcomarco 前端也加密的话,那如果是网页端岂不是加密方式都直接泄露了?
    sutra
        3
    sutra  
       2021-07-14 08:57:54 +08:00
    前端加密的意义何在?
    mingl0280
        4
    mingl0280  
       2021-07-14 09:00:19 +08:00 via Android
    密码不应当存储为明文或可逆加密的密文。
    cmdOptionKana
        5
    cmdOptionKana  
       2021-07-14 09:00:43 +08:00   ❤️ 8
    前端不加密,走 https,后端也不加密,只保存 hash
    Tardis233
        6
    Tardis233  
       2021-07-14 09:01:26 +08:00
    前后端加密肯定不是一套加密方案...不管前加不加后端肯定得独立一套方案
    feikeq
        7
    feikeq  
       2021-07-14 09:03:17 +08:00
    通常是第 3 种,前端不加密走 HTTPS,后端增添加密因子进行特定算法法加密
    InDom
        8
    InDom  
       2021-07-14 09:09:48 +08:00
    前端可逆加密,后端不可逆加密。

    如果传输协议是 https / tls 保护的,前端可以不加密。
    daguaochengtang
        9
    daguaochengtang  
    OP
       2021-07-14 09:10:09 +08:00
    @feikeq 明白了
    wangxiaoaer
        10
    wangxiaoaer  
       2021-07-14 09:11:17 +08:00   ❤️ 2
    跟楼上一样,前端不加密,但是走 https,后台拿到原始密码后给每个用户生成一个独立的盐( salt ),然后再把原始密码和盐一起做 hash,hash 结果存到数据库。 验证的时候,做同样的 hash 运算,跟数据库里面的 hash 结果比对。

    这样的好处是即使数据库泄露,也不会暴露用户的原始密码。
    dxatgp02
        11
    dxatgp02  
       2021-07-14 09:11:48 +08:00
    学习学习
    dzdh
        12
    dzdh  
       2021-07-14 09:16:16 +08:00
    不用 argon2 的都是耍流氓
    soulzz
        13
    soulzz  
       2021-07-14 09:20:12 +08:00   ❤️ 1
    直接 Spring Security 一套用上,加密方式选择 Bcrpt
    CodeCodeStudy
        14
    CodeCodeStudy  
       2021-07-14 09:27:02 +08:00   ❤️ 1
    用 BCrypt 啊
    Java

    import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
    new BCryptPasswordEncoder().encode(password);
    new BCryptPasswordEncoder().matches(rawPassword, encodedPassword);

    PHP
    echo password_hash(‘123456’, PASSWORD_DEFAULT); // 获取密码
    var_dump(password_verify(‘123456’, '$2a$10$QoH8aP4NjR.h6IJwQ4S9l.8xbryqH28UtaorHeF3uBk7h72O4J4lu')); // 校验密码
    2kCS5c0b0ITXE5k2
        15
    2kCS5c0b0ITXE5k2  
       2021-07-14 09:30:13 +08:00
    有 TLS 前端不加密也行.
    z960112559
        16
    z960112559  
       2021-07-14 09:32:25 +08:00   ❤️ 1
    前端 AES 加密
    后端 AES 解密后再 MD5()
    数据库 MD5 存储
    再加 HTTPS
    securityCoding
        17
    securityCoding  
       2021-07-14 09:34:37 +08:00
    前端加密就是在搞自己
    xmumiffy
        18
    xmumiffy  
       2021-07-14 09:44:04 +08:00 via Android
    安全的储存密码是为了不泄露用户明文密码,防止用户使用相同密码的其他服务被社工攻击。而不是为了防止调用你的接口,你密码表都被拖了,你还谈啥接口安全,直接拿你表里的 token 登入就行了。
    不过一和三都能防止你所提到的问题
    abccccabc
        19
    abccccabc  
       2021-07-14 09:48:30 +08:00
    前端页面直接将密码加密后,传到后端,后端拿着用户名与密码去数据库匹配。

    这样被社工的几率小。首先密码长度是固定的,先判断密码长度,可以过滤一部分社工。另外,密码加密传输,相对明文存储要安全很多。
    expy
        20
    expy  
       2021-07-14 09:51:46 +08:00
    3dwelcome
        21
    3dwelcome  
       2021-07-14 09:59:32 +08:00
    "只是想就事论事,想知道你们是怎么做的,这个是否有业内约定俗成的标准?"

    后端数据加密不是约定,而是强制性的。否则你网站的公安备案,都没办法正常通过。
    bfdh
        22
    bfdh  
       2021-07-14 10:08:49 +08:00
    如果没有 TLS 的话,可以考虑 challenge handshake authentication protocol 。
    bfdh
        23
    bfdh  
       2021-07-14 10:09:50 +08:00
    @3dwelcome 强制?那 CSDN 咋回事?
    3dwelcome
        24
    3dwelcome  
       2021-07-14 10:10:47 +08:00
    @bfdh CSDN 都多少年前的事情了,那时候还没有公安备案这个说法。
    xingyue
        25
    xingyue  
       2021-07-14 10:11:27 +08:00 via Android   ❤️ 1
    1 的方案按理说最好呀,不存在楼主说的问题,前端 hash(username+pwd),后端拿到后 hash(hashPwd+salt)进行存储,即便你数据库泄露了也没法得到 hashPwd,后端鉴权发 token 的接口接收的参数是 hashPwd,别人也没法调用你的接口。ps:ssl 固然安全可信,但是用户环境不可信,避免明文传输还是有必要。
    seesky
        26
    seesky  
       2021-07-14 10:18:03 +08:00   ❤️ 4
    用 1, 不仅客户端不可信, 你同事也不可信, 前端加密防止后端会因为打日志出现泄露风险。
    0bit
        27
    0bit  
       2021-07-14 10:58:50 +08:00
    @seesky 是的,据说 twitter 以前就出现过 log 密码明文的情况,还是把密码明文在前端做 Hash 之后再给后端更稳妥
    walpurgis
        28
    walpurgis  
       2021-07-14 12:15:28 +08:00 via iPhone
    hash 不是加密
    killerv
        29
    killerv  
       2021-07-14 13:20:32 +08:00   ❤️ 1
    @marcomarco 加密方式泄漏也无所谓吧,非对称加密,前端使用公钥加密,后端使用私钥解密,没什么问题的。
    killerv
        30
    killerv  
       2021-07-14 13:21:13 +08:00
    一般如果不是对安全要求特别高的场景,在 https 的基础上可以选择 3 。另外后端的密码不是加密,是 Hash,不可逆。
    Felldeadbird
        31
    Felldeadbird  
       2021-07-14 13:25:28 +08:00
    前端用最快,最容易,最简单的 hash 处理原始密码即可。
    后面有 SSL,后端二次加密,加盐,加料手段。安全已经完全足够了。
    ZeawinL
        32
    ZeawinL  
       2021-07-14 13:31:05 +08:00 via Android
    前端使用用户密码为 key 做加密或者 hash,后端对内容进行二次 hash 。
    creanme
        33
    creanme  
       2021-07-14 13:43:05 +08:00 via Android
    b 站好像是前端从接口获取一个限时的公钥,然后用公钥加密,传到后端,后端用私钥解密?
    TomatoYuyuko
        34
    TomatoYuyuko  
       2021-07-14 13:55:22 +08:00
    前端能加个毛线的密,有心破解的话很简单,你正常加盐混淆就行了不用太复杂
    ZeroDu
        35
    ZeroDu  
       2021-07-14 14:21:28 +08:00
    其实后端不一定要拿到原始密码。前端 hash 一次,后端再操作一下,直接入库
    FallenTy
        36
    FallenTy  
       2021-07-14 15:44:26 +08:00
    登陆:前端 AES 加密,后端解密 MD5 后,与数据库中的 MD5 比对
    注册:明文传输,后端 MD5 存入数据库
    SelFree
        37
    SelFree  
       2021-07-14 16:11:35 +08:00
    Hash(password) : h1 ------------> Save(Hash(h1 + salt), salt)
    xiangyuecn
        38
    xiangyuecn  
       2021-07-14 16:15:46 +08:00
    服务器端各种中间件、各种日志、各种分布式集群

    抱歉,不出意外很多都是 http 调用🐶 还不带脱敏的,惊喜不惊喜,前端对密码进行加密、hash 的重要性就比较突出了

    另外前端不传明文,对不是特意针对你网站的中间人有一定的防御力,至少不会输一下密码,人家随随便便就能知道这是明文密码

    不推荐 hash,应该用对称加密或非对称加密,并且密钥是变化的,如果不变就和 hash 没什么两样
    zhaokun
        39
    zhaokun  
       2021-07-14 16:31:37 +08:00
    1,前端简单 hash,后端再加密后存储
    zhaokun
        40
    zhaokun  
       2021-07-14 16:32:07 +08:00
    当然也有 https ( https 也不可信,大多数是可以破解的)
    Kaciras
        41
    Kaciras  
       2021-07-14 16:54:56 +08:00
    当然选 2 了,前端加密骗用户,后端明文卖密码。
    CrazyRundong
        42
    CrazyRundong  
       2021-07-14 17:58:09 +08:00 via iPhone
    @zhaokun 破解 HTTPS? 愿闻其详
    hgc81538
        43
    hgc81538  
       2021-07-14 20:30:31 +08:00
    3. 前端不加密,后端加密

    frontend:
    POST https://domain/login --data "username=admin" --data "password=12345"

    backend:
    sql = select * from `user` where `username` = :username
    result = db.get(sql, {:username => POST.username})

    if (result) {
    if ( password_verify(POST.password, result.password_bcrypt_hashed) ) {
    // login success
    } else {
    // login fail
    }
    } else {
    // user not found
    }
    Desiree
        44
    Desiree  
       2021-07-14 20:49:08 +08:00
    前端加密毫无意义,加密的算法必须由后端把控。客户端的所有信息都是不安全的。
    akira
        45
    akira  
       2021-07-14 20:55:10 +08:00   ❤️ 1
    加密后的密码 加盐 再保存到数据库
    dd99iii
        46
    dd99iii  
       2021-07-14 21:04:41 +08:00
    加盐 加盐 加盐
    otakustay
        47
    otakustay  
       2021-07-14 21:28:12 +08:00
    前端加密倒也不是完全脱裤子放屁,现在有 wasm 了反编译成本还是挺高的
    yeqizhang
        48
    yeqizhang  
       2021-07-14 22:15:13 +08:00 via Android
    25 楼说的对。
    主要是过智障安全测评不能传明文密码这一关
    streamrx
        49
    streamrx  
       2021-07-14 23:42:45 +08:00 via iPhone
    前端加密没用的 再复杂的加密,也只是增加逆向的难度而已。只有时间够长 总能找到加密的入口函数
    streamrx
        50
    streamrx  
       2021-07-14 23:43:08 +08:00 via iPhone
    前端加密没用的 再复杂的加密,也只是增加逆向的难度而已。只要时间够长 总能找到加密的入口函数
    iseki
        51
    iseki  
       2021-07-15 04:19:59 +08:00 via Android
    1,前端哈希不是防小人,是防手滑。后端必须上安全的哈希算法
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5681 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 09:02 · PVG 17:02 · LAX 01:02 · JFK 04:02
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.