验证码必须有足够的时间完成送达和输入,同时限制被猜测或重复使用的机会。在确定有效时长之前,先测量完整的验证流程。
验证码应该有效多久?
已发送的认证码(包括送达和输入时间在内)有效期不超过十分钟。
NIST 的认证指南为通过独立渠道进行的认证设定了该上限。它还要求服务器只接受验证码一次,防止在认证成功后被重复使用。
验证码验证成功时立即标记为已使用。即使尚未过期,也要拒绝对该验证码的再次提交。
十分钟是上限,而非建议的等待时长。当送达和输入的实测数据支持时,选择更短的窗口。
一个需要四十秒送达的验证码,在十分钟窗口中只剩九分二十秒。使用送达时间测量数据时,将阅读和输入时间也纳入考虑。
由身份验证器生成的验证码遵循不同的计时模型。当应用在本地生成验证码时,使用对应的 TOTP 或 HOTP 规则。
应该使用多少位数字?
至少使用六位随机生成的数字,并设置失败猜测次数限制。
NIST 要求已发送的认证密钥使用经批准的随机生成器产生的至少六位十进制数字。可预测的计数器或时间戳不满足该要求。
六位随机数字有一百万种可能的组合。五次不同的猜测有百万分之五的命中概率,即二十万分之一。
按账户计数失败的尝试次数。NIST 要求签发新验证码时保留该计数,因此重新发送不能产生无限次猜测机会。
尝试次数上限还需要为耗尽次数的合法用户提供恢复路径。决定他们如何重新获得访问权限,同时不为攻击者重置上限。
应该改用八位数字吗?
当更低的猜测概率值得让用户多输入两位数字时,使用八位。
八位随机数字有一亿种可能的组合。五次猜测的命中概率为一亿分之五。
这比五次猜测六位数字的概率低一百倍。增加验证码长度时,保持相同的尝试次数限制。
更长的验证码无法弥补无限猜测的漏洞。在将额外位数视为充分保护之前,先实现尝试次数限制。
在 Bird 中可以配置什么?
设置工作区的验证码策略。检查每次验证返回的已解析设置。
| 字段 | 如何选择 |
|---|---|
code_length | Bird 接受 4 到 8 个字符。根据本策略选择至少六位 |
code_type | 检查返回的字符集,numeric 或 alphanumeric |
ttl_seconds | Bird 接受 1 到 59940 秒。将认证窗口保持在 600 秒或以下 |
max_attempts | 选择 1 到 10 次错误提交后验证失败 |
resend_cooldown_seconds | 选择向接收者发送的间隔为 0 到 3600 秒 |
API 允许的时长超出了本认证建议的范围。请主动设置该值,而非将可接受的最大值当作合适的过期时长。
单次验证请求可以为该验证覆盖 code_length。当行为与工作区配置不一致时,检查其已解析策略。
应该如何选择?
- 从六位随机数字和一个较小的、强制执行的尝试次数上限开始。
- 根据实测的送达和输入时间确定有效期窗口,不超过十分钟。
- 当操作需要更低的猜测概率时,使用八位数字。
- 强制一次性使用,并在签发新验证码时保留失败尝试计数器。
简而言之
有效期不超过十分钟。
送达和输入都会消耗有效期窗口。当实测流程支持时,选择更短的时长。
至少使用六位随机数字。
在选择验证码长度的同时,也要计数失败的猜测次数。更长的验证码不能替代尝试次数限制。
每个验证码只接受一次。
即使有效期窗口尚未结束,也要拒绝已被接受过的验证码。
重新发送时保留尝试计数器。
签发新验证码不能给账户带来新的猜测机会。