动态口令(OTP,One-Time Password)原理与实践(TOTP)

本文介绍了TOTP(基于时间的一次性口令)的工作原理和实现过程,包括如何生成密钥、构造扫码字符串、生成二维码和动态口令。讨论了时间同步的重要性以及为提升用户体验和安全性所采取的策略,如动态口令的有效期管理、消息下发和事件驱动的动态口令生成机制。
部署运行你感兴趣的模型镜像

TOTP:Time-Based One-Time Password Algorithm,基于时间同步的一次性口令,动态口令

技术标准:https://tools.ietf.org/html/rfc6238

参考链接:

https://blog.youkuaiyun.com/LVXIANGAN/article/details/73775969

https://www.cnblogs.com/loveyou/p/6989064.html

 

使用阿里云身份宝(或者Google Authenticator)时间同步实现OTP动态口令

  如上图,是一种基于时间同步的OTP计算方式,是通过客户端和服务器持有相同的密钥并基于时间基数,服务端和客户端采用相同的Hash算法,计算出长度为六位的校验码。当客户端和服务端计算出的校验码相同是,那么验证通过。

   由于客户端需要存储密钥和计算校验码的载体,阿里云的身份宝(或者Google 的Authenticator)提供了手机端的APP进行密钥存储和校验码计算。下面我们以这两款客户端为例,实现在应用采用OTP进行权限验证,主要流程如下图:

 

【生成密钥】

String secretBase32 = TotpUtil.getRandomSecretBase32(64);

oper.setOtpSk(secretBase32);

【构造扫码字符串】

格式:otpauth://totp/[客户端显示的账户信息]?secret=[secretBase32]

String totpProtocalString = TotpUtil.generateTotpString(operCode, username, secretBase32);

【生成二维码】

QRUtil.generateMatrixPic(totpProtocalString, 150, 150, filePath, fileName);

【生成动态口令】

secretHex = HexEncoding.encode(Base32String.decode(secretBase32))

long timeStep = 30L; // 动态口令有效性持续的时间区间 30s

steps = Long.toHexString(System.currentTimeMillis() / 1000L / timeStep).toUpperCase();

steps = "000000000000".substring(0, 16-steps.length())+steps;

generateTOTP(secretHex, steps, "6", "HmacSHA1");

=========================================================================================

显然验证的时候要求客户端和服务端时间上基本同步,二者相差应该在 timeStep 以内,否则客户端和服务端计算得到的动态口令就不一致。

这一特性使得用户必须在 timeStep 时间内获取并输入、提交动态口令。从算法看能够成功验证的时间区间在时间轴上是长度为 timeStep 前后排列、紧密连接的时间窗口。一旦用户获取动态口令的时间和服务端验证动态口令的时间不在同一个时间区域内,验证将失败。

如果把时间窗的大小 timeStep 设置大一点,可以降低正常验证中因错开时间窗导致失败的概率。但这又引入另外一个问题:如果用户某次使用的动态口令被泄露,那么在一定时间内被泄露的动态口令还可以成功地被用来做身份验证。

① 为提升用户体验同时保证安全性,此处对验证环节做一些调整:

数据库中除了存储用户信息和密钥之外,建立一张表用于存储和管理近期的动态口令。

假设约定动态口令的有效期为2分钟,每 timeStep=30 秒生成新的动态口令。那么从 t0 开始存入第 1 个动态口令,t0+30s 后存入第 2 个动态口令,t0+60s 后存入第3个动态口令, t0+90s 后存入第4个动态口令,t0+120s 后删除 t0 对应的动态口令,插入第 5 个动态口令,以此类推,数据库中总是存有 1~4 个有效的动态口令。当服务端收到一次动态口令认证请求时,只要传入的口令与数据库中存储的该用户对应的任意一个动态口令相同,那么验证成功,并删除数据库中相应的口令记录(表示已经使用过,宣布失效)。

这样只要用户在提交验证请求前 90秒内获取动态口令那么验证肯定是成功的。如果是提交验证请求前 90~120秒 获取的动态口令,那么可能验证成功,也可能失败。

② 动态口令的另一种使用方式:消息下发

消息下发的形式最常见的就是短信、邮件、IM。

服务端根据用户信息、时间和密钥生成并临时存储动态口令,然后将口令发送给用户,在约定的时间内用户提交收到的动态口令,服务端在比对后判定验证结果。

③ 事件驱动的动态口令生成和传递机制:

如上所述,如果服务器每隔 timeStep 时间就得更新一下数据库里所有用户的动态口令,由于动态口令只有在用户登录认证的时候才会使用,那么势必带来计算浪费。

一个变通的实践方法是:

当服务端收到认证请求时即时生成4个动态口令,这4个口令分别对应当前时间 t0、t0-30s、t0-60s、t0-90s 四个时间点对应的动态口令。

查找验证历史记录表,找出相应用户在时间大于 t0-90s 的范围内的验证成功的记录,在4个动态口令中去除已经验证过的口令。

然后将用户提交的口令与最近的 0~4 个有效口令进行比对,如果无一匹配那么验证失败;如果有一个匹配那么验证成功,并将对应的验证事件(用户,动态口令,验证结果,时间)存入数据库。

考虑认证服务和安全监控的需求,可以将每次认证(不论成功、失败,或用户提交了已经使用过的动态口令)事件都记录下来,用于帮用户分析认证失败的原因,以及监控动态口令可能被劫持盗用等行为。

 

转载于:https://www.cnblogs.com/shilxfly/p/9438235.html

您可能感兴趣的与本文相关的镜像

Qwen-Image

Qwen-Image

图片生成
Qwen

Qwen-Image是阿里云通义千问团队于2025年8月发布的亿参数图像生成基础模型,其最大亮点是强大的复杂文本渲染和精确图像编辑能力,能够生成包含多行、段落级中英文文本的高保真图像

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值