You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何比对用户输入的SMS验证码与Database中存储的验证码

SMS验证码与数据库存储值比对方案说明

你提到的直接通过SQL查询语句执行比对逻辑的方案可以跑通,但不推荐在生产环境使用,存在不少隐患,更稳妥的实现方式可以参考下面的逻辑。

直接在Query层做比对的核心问题

  • 存在时序攻击风险:数据库原生的字符串等值匹配是逐字符判断的,不同输入的响应时间会存在可测量的细微差异,攻击者可以通过响应时间差逐位爆破出有效验证码。
  • 业务逻辑耦合度高:验证码的过期判断、错误次数熔断、一次性失效等规则如果全部写在SQL语句中,后续迭代维护成本极高,很容易出逻辑漏洞。
  • 存在敏感信息泄露风险:如果开启了数据库慢查询日志、全量执行日志,用户传入的明文验证码会直接落在日志文件中,不符合数据安全合规要求。

生产环境推荐实现流程

  • 前置校验层先做基础拦截:先校验用户传入的手机号格式、验证码长度/字符规则是否符合要求,格式非法的请求直接返回参数错误,不需要穿透到存储层。
  • 存储层仅做单条件查询:仅以用户手机号/业务唯一标识作为查询条件,取出对应存储记录中的加盐哈希后的验证码密文、过期时间戳、已验证状态、累计错误次数字段。不要把用户输入的验证码作为SQL查询条件传入。

    注意:验证码禁止明文存储,需要和用户密码存储逻辑一致,生成验证码时就做加盐哈希后再落库,避免数据库拖库后验证码直接泄露。如果是短生命周期的验证码场景,优先用Redis存储,性能比关系型数据库高很多,操作逻辑和关系型库一致。

  • 内存中完成安全比对:
    1. 先判断记录是否存在、是否已过有效期、是否已经被标记为已使用、错误次数是否达到熔断阈值,任意一项不满足直接返回验证失败,同时更新错误计数。
    2. 对用户传入的明文验证码做相同规则的加盐哈希,用编程语言提供的常量时间字符串比较函数和存储的密文做比对,不要直接用普通的==/===等值判断符,从底层避免时序攻击。
  • 比对完成后做状态更新:
    • 比对成功:立刻将该条验证码记录标记为已失效(验证码必须设置为一次有效,防止重复验证绕过),清空错误计数,返回验证通过结果。
    • 比对失败:将该记录的累计错误次数+1,如果错误次数达到预设阈值(比如连续错3次)直接将该条验证码标记为失效,返回验证失败结果。

内容的提问来源于stack exchange,提问作者Krios

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 05:39:40