算法~totp用作签名防止url被复用
之前写过关于totp的文章,对它的基础有不清楚的同学,可以先看我的这篇文章《TOTP基础一》《TOTP基础二》
想到的问题
因为totp是把时间分成了一个一个小的时间窗口,当生成totp的服务器和校验totp的服务器不在一起时间窗口,就会出现验证失败的问题,这是不可避免的,时间戳是一个long类型的数字,当这个数字进行totp运算后,落在哪个窗口里是确定的,但你的时间戳数字是不确定的,因为你不知道用户在什么时间触发totp这个生产的动作。
时间窗口
从下面的图中可以看到,时间两个窗口总会有一个交叉,谁赶上了都不一定,所以我们要解决这个不一定的问题。
最多跨一个窗口
我们的生成totp端和校验totp端,他们最多相差一个窗口,当然这也取决于,生产和校验的时间差和你的窗口大小,正常情况下相差1个窗口,所以我们比较上一个和下一个窗口即可。
/**
* 生成一组TOTP,窗口大小5分钟,产生8位的动态码.
* @param base32Key
* @return
*/
public static List<String> generateTOTPList(String base32Key) {
long currentTime = System.currentTimeMillis();
long prevTime = currentTime - 30 * 1000;
long nextTime = currentTime + 30 * 1000;
List<String> result = new ArrayList<>();
result.add(generateTOTP(prevTime, base32Key, 300, 8));
result.add(generateTOTP(currentTime, base32Key, 300, 8));
result.add(generateTOTP(nextTime, base32Key, 300, 8));
return result;
}
我们在进行校验时,用这3个totp码与目标totp进行对比,有一个满足,就说明是合法的!即,我们的容错率是前后1个窗口。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 【.NET】调用本地 Deepseek 模型
· CSnakes vs Python.NET:高效嵌入与灵活互通的跨语言方案对比
· DeepSeek “源神”启动!「GitHub 热点速览」
· 我与微信审核的“相爱相杀”看个人小程序副业
· Plotly.NET 一个为 .NET 打造的强大开源交互式图表库
2017-11-16 DotNetCore跨平台~xUnit和测试报告
2017-11-16 DotNetCore跨平台~Dapper的使用