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

用户口令(密码)应该如何传输?要不要加密? HTTPS 呢?举例分析

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

    假设

    口令在信道中传输时不会被窃取(就是未被安装伪造证书的 HTTPS ),但服务端被攻破

    1. 明文请求登录和存储

    攻击者得到了用户的口令明文,可以去其他站点尝试输入登录

    2. 哈希请求登录和直接存储

    攻击者得到了用户的口令哈希,可以构造请求去其他站点尝试登录

    3. 哈希请求登录和加盐存储

    攻击者在拿到服务端日志或执行权限时,可能获得口令哈希,然后构造请求去其他站点尝试登录

    4. 加弱盐哈希请求登录和加强盐存储

    例如,前端用SHA256($password + $hostname)请求登录,服务端用SHA256($hash + $salt)存储。 攻击者可能得到请求的哈希值,但因为加盐的存在,即便用户在其他站点使用相同口令,也无法重新计算哈希构造请求登录

    总结

    第 4 种方法是最安全的。当然我们作为用户,还是每个站点都使用独立口令最好

    后记:刚拔完智齿,闲得无聊,把很久以前的思考整理成文

    第 1 条附言  ·  56 天前
    补充两点:
    1. 服务端被攻破时,“我”仍有能力关机下线服务
    2. 将“当自己的服务被攻击时,保护用户在其他在站点的账户不被波及”当作安全义务
    54 条回复    2024-08-05 00:19:48 +08:00
    processzzp
        1
    processzzp  
       56 天前   ❤️ 1
    SRP 可以了解一下,比你自己在那里闭门造车安全多了
    https://en.wikipedia.org/wiki/Secure_Remote_Password_protocol
    FengMubai
        2
    FengMubai  
    OP
       56 天前
    @processzzp 你说的对。我想说的并不是如何实现,只是在 v 站有过很多次关于“HTTPS 还要不要加密口令”的讨论,我现在有了闲心跟进讨论
    aababc
        3
    aababc  
       56 天前
    咋感觉少了一种情况,就是 明文请求,hash 存储
    v2tudnew
        4
    v2tudnew  
       56 天前
    用户肯定是希望站点安全保管账户信息......
    msg7086
        5
    msg7086  
       56 天前
    这话题好像每次都会变成吵架贴呢……
    FengMubai
        6
    FengMubai  
    OP
       56 天前 via Android
    @aababc 和第 2 种实际上是一样的,因为假设信道是安全的,只是执行哈希计算的位置不同
    clf
        7
    clf  
       56 天前
    哈希加盐存储,明文请求

    快进到不允许密码登录,只能验证码/扫码/第三方 oauth
    aababc
        8
    aababc  
       56 天前
    再结合前两天看到的,密码门锁的 虚位密码 感觉又是另一种情形了!
    Puteulanus
        9
    Puteulanus  
       56 天前
    既然服务端已经被攻破,那你怎么防止攻击者直接修改你的前端代码来从用户手里获取明文密码呢
    FengMubai
        10
    FengMubai  
    OP
       56 天前
    @Puteulanus 说得好,但不影响第 4 种方法是这 4 种里最安全的
    henyi2211
        11
    henyi2211  
       56 天前   ❤️ 1
    Challenge - Response 模式,连密码都不用传
    jinliming2
        12
    jinliming2  
       56 天前 via iPhone   ❤️ 1
    HTTPS 下面传明文就足够,其他轮子意义都不大。
    在不破坏 HTTPS 的情况下,明文不会有问题。
    在 HTTPS 被破坏了,比如中间人,或者 HTTPS 用了过时不安全的算法,那么:
    传 HASH:直接截取重放即可。
    传带时间戳的 HASH:要求服务端明文存储用户密码。
    用加密算法加密:不管对称还是不对称,都需要给客户端下发加密密钥,HTTPS 被破坏的情况下,中间人可以替换下发的密钥,做代理。
    客户端预置密钥/公钥:你重新实现了 TLS 。
    GeekGao
        13
    GeekGao  
       56 天前
    Okta API 传的是明文,我想世界上没有第二家比之规模更大的身份管理厂商了吧。
    murmur
        14
    murmur  
       56 天前
    base64+https 就可以了,https 都被劫持了你的 js 文件是不是真的都是两回事,base64 完全是为了对付等保

    上次有个等保扫我们,说我们所有的 api 路径都用了明文,无语,还专门写了个代码把所有的接口地址都改成\xx\xx\xx\xx 这样的写法
    FengMubai
        15
    FengMubai  
    OP
       56 天前 via Android
    @jinliming2 你说的对,但是你完全忽视了我的假设
    jdkxnktkdkxod
        16
    jdkxnktkdkxod  
       56 天前
    不知道你在说什么,就算攻击者得到用户的口令哈希,他怎么去构造请求登录其它站点?你该不会以前口令哈希是前端请求的时候构造的吧?
    jdkxnktkdkxod
        17
    jdkxnktkdkxod  
       56 天前
    不知道你在说什么,就算攻击者得到用户的口令哈希,他怎么去构造请求登录其它站点?你该不会以为口令哈希是前端请求的时候构造的吧?
    jdkxnktkdkxod
        18
    jdkxnktkdkxod  
       56 天前   ❤️ 1
    还有你这第四种,“前端用 SHA256($password + $hostname)请求登录,服务端用 SHA256($hash + $salt)存储”,你要不好好看看你在说什么?
    Nosub
        19
    Nosub  
       56 天前 via iPhone   ❤️ 1
    和 op 主几乎一样的想法和实现,用的方法 4 ,

    https://nosub.net/posts/p/104
    chinni
        20
    chinni  
       56 天前
    我见过的一个网站就是 每次先请求一个 rsa pubkey 然后用户密码加密后传到后端 反正后端有 privkey 解密.. 存的话怎么存都行了 反正能比就好 很多成功例子
    kyuuseiryuu
        21
    kyuuseiryuu  
       56 天前
    TLS 是传输层加密,传输层不可靠那就只能再往上一层那就是应用层加密了。
    服务端的应用层那就是源码级加密。程序用私钥加密,通过启动器从环境变量加载公钥启动应用。这样即使攻破服务器也查看/修改不了源码,从而保护业务逻辑。
    浏览器 -> 服务端则要求用户注册的时候保存用户的公钥,之后所有的请求需要用户私钥加密传输。服务端使用用户注册的公钥解密请求。这样只要保证用户注册时是安全的即可。用户的公私钥对要可以通过 yobikey 之类的东西实现。没错,就是以前的网银盾。
    murmur
        22
    murmur  
       56 天前
    @jdkxnktkdkxod 很明显楼主连加盐都没搞清楚,这玩意只能防止脱库后被逆出明文密码,然而现在是全实名制,人家已经改了 https 证书,进了你的服务器,就可以拿到代码逆向出手机号、身份证等更多数据

    怎么说呢,除了不能给彩虹表提供数据,真的惨
    EndlessMemory
        23
    EndlessMemory  
       56 天前
    散列值+盐就行了,没有绝对的安全,增加攻击者的成本就行了
    FengMubai
        24
    FengMubai  
    OP
       56 天前 via Android
    @jdkxnktkdkxod “+”为自定义运算,你可以用简单的字符串拼接,$hostname 代表着前端的盐是一个公开的固定的值,$salt 是来自随机数发生器的和哈希等长的盐。也就是说,即便用户使用相同的口令,那么服务端接受到的请求中的口令字段,也无法用于去撞隔壁的站点;服务端再次加盐,就是常规目的了
    FengMubai
        25
    FengMubai  
    OP
       56 天前 via Android
    @murmur 很显然你并没有理解我想讨论什么。我并没有说这样做可以保护服务端被攻破时避免数据泄露,我只是想讨论,口令要如何传输(当然不传最好
    murmur
        26
    murmur  
       56 天前
    @FengMubai 你想太简单了,我都上了你服务器了,你的代码还是你写的么,我如果不想搞你直接删库留个比特币的勒索条子,想搞你我代码都可以给你改掉

    你的前提是服务器被“我”攻破,那你所有的代码还是你之前写的吗
    FengMubai
        27
    FengMubai  
    OP
       56 天前 via Android
    @murmur 你说的对,你想的很全面,但是如果不设置一个假设范围的话,任何讨论都将没有讨论的意义
    huihuimoe
        28
    huihuimoe  
       56 天前
    草,服务端都被攻破了,你还想着正经拿 post 内容构造???
    直接改服务端插点 js 直接把所有用户动作上报不就好了,想要啥东西都给你传回来啊
    FengMubai
        29
    FengMubai  
    OP
       56 天前 via Android
    @huihuimoe 我总可以拔电源吧,尽管数据你都拿到了
    FengMubai
        30
    FengMubai  
    OP
       56 天前 via Android
    @huihuimoe 我说的构造 post ,不是“我”的站,是隔壁的站
    EminemW
        31
    EminemW  
       56 天前
    @jinliming2 那啥,服务端就不应该明文存用户的密码,存明文密码有点窥探用户隐私的意思了
    keithwhisper
        32
    keithwhisper  
       56 天前
    方案 4 比较有责任心, 不过大部分开发是没有这个心思的.

    用户密码明文出现在服务端一侧, 就可以被社会工程学攻击, 以前就有过用户密码明文被日志记录的例子.

    当然, 有人会骄傲地说, "你们日志不去敏, 你们不专业", 他们应该去看一下 "墨菲定律"

    > Anything that can go wrong will go wrong.
    hubaq
        33
    hubaq  
       56 天前
    服务端都被攻破,任何安全手段都是脱裤子放屁
    panda1001
        34
    panda1001  
       56 天前 via Android
    前端 js 混淆后加密提交参数,至少增加了爆破门槛
    hubaq
        35
    hubaq  
       56 天前
    @panda1001 服务器都被攻破了,加密也没用啊,我直接修改前端代码不加密
    MFWT
        36
    MFWT  
       56 天前
    我可能有点敏感,不过我写的小项目也是用的方法 4 ,防重放肯定是做不到,但至少可以让明文密码不离开用户机(你说用户机被攻破了.......那算了)
    SP00F
        37
    SP00F  
       56 天前
    😰 没有讨论的价值,服务器都破了。拿着你最高权限都懒得管你加不加密了
    FengMubai
        38
    FengMubai  
    OP
       56 天前 via Android
    @SP00F 看你愿不愿意把“当自己的服务被攻击时,保护用户在其他在站点的账户不被波及”当作安全义务了
    FengMubai
        39
    FengMubai  
    OP
       56 天前 via Android
    @MFWT 重放攻击是另外的话题了,如果你想讨论,可以新开一个贴
    Tstxxy
        40
    Tstxxy  
       55 天前
    首先客户端的代码,花时间肯定能知道你的逻辑。
    其次,服务器被攻破,花时间也肯定能知道服务器代码的逻辑。
    因此,上面四种方案属于脱裤子放屁。
    FengMubai
        41
    FengMubai  
    OP
       55 天前 via Android
    @Tstxxy 现密码学的思想是:算法可公开,安全性靠密钥保证,对于非对称密码甚至可以公开密钥,哈希密码甚至没有任何必须隐藏的东西了。你再花时间想想
    byte10
        42
    byte10  
       55 天前
    @Tstxxy 😂,很多人都是这样想的。

    楼主我再告诉你 2 个案例,有人说 cookie 不安全,别人登陆你电脑拿到 cookie 就可以登陆你淘宝。还有人说家里的门不安全,因为你钥匙掉了,或者被偷了就会被盗窃。

    你提出的问题 跟上面没啥区别。目前市面 95%的 app ( web )都不会通过客户端加密来请求登录的(当然做了是更好),微信和支付宝虽然我没研究过,但是花 5000 块钱 肯定是可以拿到你说的那些啥前端加密的方式😂 。

    有安全级别比较高的 app ,比如支付宝,他们就需要你的人脸识别,短信验证等。
    FengMubai
        43
    FengMubai  
    OP
       55 天前 via Android
    @byte10 同上,我并没有想要隐藏我的加密过程
    byte10
        44
    byte10  
       55 天前
    @FengMubai 嗯,你说的 不可逆的算法确实可以保护好用户的明文密码是可行的。刚看错了。
    Anarchy
        45
    Anarchy  
       55 天前
    这些逻辑都基于把密码当做用户隐私做安全措施,那用户隐私是什么级别的安全防护?当然明文存了。
    DeWjjj
        46
    DeWjjj  
       55 天前
    在登入系统独立的情况下,密码可以由多个字段处理管理。
    例如捆绑 ip ,换 ip 验证信息丢失。
    验证器,例如谷歌等。
    手机验证码,小金额保护。
    人脸验证,大金额保护。

    安全措施很多,不仅要只做密码一层。
    murmur
        47
    murmur  
       55 天前
    @byte10 你那算什么案例,拿到 cookie 就可以登陆淘宝意味着黑产可以随便做机器人,实际上你猜猜淘宝有多少风控系统
    ifbluethen
        48
    ifbluethen  
       55 天前
    4 感觉拿到 hash 后的密钥就能用 api 工具伪造请求,只是没有明文密码而已吧
    jinliming2
        49
    jinliming2  
       55 天前 via iPhone
    抱歉抱歉,确实没仔细看假设。
    不过,对于 Web 业务,如果服务端被攻破,那么就完全有能力改造用户端的登录页面,直接去除 hash 逻辑,把明文带上来。
    当然,这里假设服务端被攻破是指能控制前端代码的服务端被攻破。
    ryanlid
        50
    ryanlid  
       55 天前
    服务器被攻破了,别人在下载用户数据,你却在破译用户密码
    lthon
        51
    lthon  
       55 天前   ❤️ 4
    如果基于 Kerckhoffs's principle ,那么不能依赖客户端的服务器不被攻破,所以方案 3 和 4 是一样的。
    搜索到 https://crackstation.net/hashing-security.htm ,这篇文章说得非常好,建议得方案比 OP 第 4 种稍作了一些变化,前端的 hash 函数使用标准密码哈希函数(例如 Argon2 、bcrypt 、scrypt 或 PBKDF2 )而不是 SHA256 ,目的是减慢 hash 速度。
    FengMubai
        52
    FengMubai  
    OP
       55 天前
    @lthon 终于有人是完全在讨论应用密码学而不是程序设计了
    wdssmq
        53
    wdssmq  
       55 天前
    PBKDF2 - PBKDF2 演示封装 - 水水的演示站
    https://demo.wdssmq.com/tools/PBKDF2/

    之前 v 友说如果确实要弄可以用这个方案。。
    SP00F
        54
    SP00F  
       55 天前
    @FengMubai #38 首先要考虑的是如何防止数据泄露、数据脱敏、服务器最高权限被拿下。再去考虑密码的问题,即便没有拿到最高权限,当渗透的主要目的只是脱裤的时候,最高权限不是对方的目的,对方的目的可以通过供应链、劫持等渠道篡改部分前端代码( Web ),在构造请求前就可以把活跃用户的账号密码“脱”下来。

    还有做埋点记录的,这一块属于供应链侧的攻击,你要考虑你的用户群体是否存在被脱裤的价值,如果有那优先考虑如何防止在低权限的情况下甚至不是以攻击你方服务器的情况下获取到用户信息。

    担心在传输过程中出现问题得考虑中间人的问题,再去加密即可。

    安全是无形的成本,钱嗷嗷花,东西看不见。出问题的时候这钱花得又觉得不值,老板高管不懂安全的又要骂又要砍。

    为什么小公司几乎都不会考虑更深的安全问题就在这里了。即便大公司,说实话的,当攻击面扩大的时候,已经不是考虑密码传输加密不加密的问题了。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   867 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 21:25 · PVG 05:25 · LAX 14:25 · JFK 17:25
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.