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

为什么不结合签名的方式优化登录流程

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

    其实这个疑问在现在这个时间节点上不应该成为问题,因为现在的网络协议都基本带上 ssl 了,如 https 。

    但在当初不普及 https 的网络年代,抓包的方式很容易捕获传输数据,特别是像密码这样的数据。 先说一下以前乃至现在比较常规的登录方式吧。

    无非就是客户端/web 输入 usernameMD5(password) ,然后 post 的方式提交到服务器,尽管 password 使用了 MD5 函数,但是结果还是不变的,只要密码没有被修改,这个值是不会变的,别人盗取了这部分数据依旧可以模拟你的登录。 但,如果流程这个环节使用签名的方式,就不一样了。

    让客户端设置一个当前时间戳 timestamp , 登录时将 username + timestamp 则为明文 P,然后用 MD5(password) 为签名秘钥 S,得出 sign = HASH(P+S)。

    传输的过程中仅将 username, timestamp , sign 提交到服务器,那么即时明文状态下被抓包,对方也无法得出关键数据 password or MD5(password),而且服务端可以根据 timestamp 计算时间差,比如 5 秒内有效,使得监听者在超过时效范围内无法通过重放请求实现登录。

    这个就是单纯的签名流程在现在的开放平台上(openapi)应用非常广,理论上当时就应该有,可是为什么在 http 流行的网络年代没有被应用在登录流程上。

    17 条回复    2023-12-07 09:20:30 +08:00
    flyqie
        1
    flyqie  
       96 天前 via Android
    你这方案能防盗号,但是仍然可以在其他点抓包拿其他信息。。

    可能是觉得成本和回报不成比例?
    tool2d
        2
    tool2d  
       96 天前
    其实是有的,只是你不知道。

    2005 年左右 mysql 很火,远程登录并没使用 SSL 加密协议,但密码还是用服务器返回的 token 加密过了。就是为了防抓包。
    i8086
        3
    i8086  
       96 天前
    楼主说得这一套,网易和腾讯是有用上的。
    element90
        4
    element90  
    OP
       96 天前
    @flyqie 在那个年代,成本显然是低于 ssl
    element90
        5
    element90  
    OP
       96 天前
    @tool2d 哈哈,可能是我孤陋寡闻了,因为当年我在参加工作的时候没有考虑到这么多,同时也没有任何人或者在任何团队上看到这种方式,所以完全没有看到这方面的应用,直到现在突然联想到这个问题发现当时没人这么做非常不合理。原来早就有了啊。。但是没有大规模形成实现标准,这也非常不合理啊
    element90
        6
    element90  
    OP
       96 天前
    @i8086 那可能是我孤陋寡闻了
    muzuiget
        7
    muzuiget  
       96 天前
    你整套加密方法被中间人都知道的话,你加密花活再多也没用,中间人一样可以推理出来,“信任链“了解一下。
    liuidetmks
        8
    liuidetmks  
       96 天前   ❤️ 1
    HMAC ?
    victimsss
        9
    victimsss  
       96 天前
    别说优化了,当时还有网站明文保存密码呢。
    flyqie
        10
    flyqie  
       96 天前 via Android
    @victimsss #9

    你说起这个我突然想起来 csdn 。。
    Seulgi
        11
    Seulgi  
       96 天前
    就是一个安全性的考虑问题而已。当年还没到考虑安全的地步,就跟当年还没到考虑高并发高可用的地步一样。都是一步一步升级来的。
    laqow
        12
    laqow  
       96 天前
    现在小鬼全在 VPS 练手,抓包都没出第一级路由就被抓了,5 秒能重放无数遍了吧
    shellus
        14
    shellus  
       96 天前
    sign = HASH(username + timestamp + MD5(password) )。

    POST Login:{ username, timestamp , sign }

    服务端怎么验证 sign ?需要服务器持有 MD5(password) 是吧?

    风险点 1:服务器持有固定的 md5

    风险点 2:登陆后得到的 token 或 sessionId ,仍然可以被利用。

    风险点 3:后续请求没有整体签名和加密,仍然可以被监听和篡改。

    最重要的,这个方法没有办法阻止中间人返回钓鱼页面或者注入恶意 JS 代码,中间人可以篡改登陆页面响应,注入一段键盘监听的 JS 脚本,或者干脆返回整个假的页面诱使用户输入密码。
    element90
        15
    element90  
    OP
       96 天前
    @muzuiget @shellus 你们不需要考虑中间人问题,因为这个问题的建立是在“当时 http 盛行”的环境内。这个只是改良登录传输密码的环节,所以你应该对比的是“直接传输密码” vs “签名隐藏密码”的安全差异。

    这个问题主要在于,为什么当时连这个改良都没有
    muzuiget
        16
    muzuiget  
       95 天前
    @element90 不考虑中间人的话,何必要搞这种花活。
    shellus
        17
    shellus  
       87 天前
    @element90 因为第一点,服务器必须持有固定的密码 MD5 ,而实际上,服务器一般储存密码哈希,这个密码哈希是随机加盐的,同一个密码每次计算出来都是不一样的,这样可以完全防止服务端密码泄露后可能产生的撞库攻击。
    如果为了在传输环境增加一点点毫无用处的密码泄露风险,而导致在数据库要储存几乎等同明文密码,我觉得得不偿失
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   2535 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 03:50 · PVG 11:50 · LAX 19:50 · JFK 22:50
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.