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

关于短信/邮箱验证码的设计

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

    在做一个金融类的 app,对安全性要求较高。一个注册功能我设计了 4 个接口,才能完成注册,其中第一步:输入邮箱。第二步验证邮箱,第三步验证手机,第四步输入密码,产品还要求一段时间内验证完某个步骤后中间中断了,下次进来直接跳到下一步

    还有其他比如首次登陆,更改密码。更改手机绑定,都需要这个功能,我应该如何设计呢? 如果不考虑注册的这个,因为他设计到要跳过某个步骤。我想的是两个接口 /sendCode(type:"sms", "12425724234", "scene": "login") return token token = md5("sms"+ "12425724234" + scene), 存到 redis, 10min 过期 /verifyCode(token) 如果验证成功,生成一个 authToken, 存到 redis,返回一个 authToken, 后续比如更改密码接口,带上这个 autToken?,authToken 只能被使用一次,验证后就从 redis 删除,authTOken = md5(token+time.Now())

    这样设计如何呢?

    7 条回复    2024-05-16 15:01:14 +08:00
    lasuar
        1
    lasuar  
       176 天前
    都对安全性要求较高了,还用 md5? 换一种低碰撞 hash 算法,或者使用一种唯一 id 生成算法,而且最后都要写入 MYSQL 来保证唯一(唯一键),这个表可以是一个月表。
    按需求,每个步骤都要返回一个 step_token 给客户端,下次传给服务器,解析后直接进入下一步,所以你的 authToken 是什么用途?对于更改密码这种敏感操作肯定是没有延续的说法吧,一般都是在一个页面中完成,要么是在验证原密码后发送一个带有效期的链接到邮箱,链接中带的也应该是一个 step_token 。
    至于包含 4 步的注册功能,服务器可以通过一种状态机模式来实现。比如设计出四种状态:input_email 、verify_email 、verify_phone 、input_passwd ,没带 token 就是第一种状态,否则就是从 token 从解析出到了哪一种状态,然后执行对应的状态流转逻辑。
    RandomJoke
        2
    RandomJoke  
       176 天前
    本身验证码这件事就发码和验证两件事情, 其他的步骤改密都是应用层业务, 那么安全问题就是, 防止恶意发码攻击, 防止碰撞验证
    dododada
        3
    dododada  
       176 天前
    至少 sha256+盐,加上 ip ,imei ,mac ,频率校验等操作,再和上面讲的发码验证分开
    yuyang1992test
        4
    yuyang1992test  
    OP
       176 天前
    @jokefaker 比如改密操作吧,可能需求就是邮箱验证,手机号,验证,最后输入新密码,这样的话得好几个接口,那我在最后一个改密的接口总得校验下是不是有没有通过验证,所以我可能需要一个标识
    kkocdko
        5
    kkocdko  
       176 天前   ❤️ 3
    这边大家都是零零碎碎地说,我是觉得如果你工期紧,得尽早找个熟悉的人问。

    如果你有空的话,可以详细阅读

    《 OWASP 安全编码规范快速参考指南》

    https://github.com/OWASP/www-chapter-china-mainland/blob/master/OWASP%E5%AE%89%E5%85%A8%E7%BC%96%E7%A0%81%E8%A7%84%E8%8C%83%E5%BF%AB%E9%80%9F%E5%8F%82%E8%80%83%E6%8C%87%E5%8D%97.pdf

    《加盐 hash 保存密码的正确方式》

    https://github.com/su18/wooyun-drops/blob/b2a5416/papers/%E5%8A%A0%E7%9B%90hash%E4%BF%9D%E5%AD%98%E5%AF%86%E7%A0%81%E7%9A%84%E6%AD%A3%E7%A1%AE%E6%96%B9%E5%BC%8F.md

    设计一个充分可靠的注册、登录、鉴权体系,其实是比较复杂的。特别是你提到了“在做一个金融类的 app,对安全性要求较高”。
    sampeng
        6
    sampeng  
       175 天前
    再高点。。。app 要用自己定义的密码输入。。🐱
    ZXiangQAQ
        7
    ZXiangQAQ  
       175 天前
    再高点,第一步,客户端向服务端申请一个国密 2 算法的公钥,后面的步骤里邮箱、手机号、密码都通过这个公钥加密,服务端通过 redis 缓存私钥,有过期时间限制
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3020 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 21ms · UTC 13:41 · PVG 21:41 · LAX 05:41 · JFK 08:41
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.