如何应对基于时间的一次性密码中的26字节秘密?
来源:stackoverflow
时间:2024-02-11 09:18:25 349浏览 收藏
本篇文章主要是结合我之前面试的各种经历和实战开发中遇到的问题解决经验整理的,希望这篇《如何应对基于时间的一次性密码中的26字节秘密?》对你有很大帮助!欢迎收藏,分享给更多的需要的朋友学习~
基于时间的一次性密码的秘密通常是 16 字节的 base32 编码字符串。例如github 2fa。
但对于某些场景,它有 26 个字节长。例如图塔诺塔 otp。通常是带有空格的小写字母,例如:vev2 qjea un45 3sr4 q4h3 ais4 ci
我尝试使用在 dgryski/dgoogauth 和 tilaklodha/google-authenticator 中实现的 totp 算法。两者都可以很好地处理 16 字节机密,但处理 26 字节机密时会出错。
例如对于 16 字节秘密 vev2qjeaun453sr4
:
time: 2021-12-17 14:31:46 got: 079119
对于 26 字节秘密 vev2qjeaun453sr4q4h3ais4ci
:
error: "illegal base32 data at input byte 24"
这是代码片段:
func getHOTPToken(secret string, interval int64) (string, error) { // Converts secret to base32 Encoding key, err := base32.StdEncoding.DecodeString(secret) if err != nil { return "", err } // Signing the value using HMAC-SHA1 Algorithm hash := hmac.New(sha1.New, key) err = binary.Write(hash, binary.BigEndian, uint64(interval)) if err != nil { return "", err } h := hash.Sum(nil) // Get 32 bit chunk from hash starting at the offset offset := h[19] & 0x0f truncated := binary.BigEndian.Uint32(h[offset : offset+4]) truncated &= 0x7fffffff code := truncated % 1000000 return fmt.Sprintf("%06d", code), nil }
你能告诉我如何处理26字节的秘密吗?
正确答案
一个base32将输入字节的每5位编码成base32字符,去base32使用 rfc 4648 base 32 字母表(a-z、2-7)。当将字符串解码为字节时,每个base32 字符输入将映射到 5 位索引,然后重新组合为字节。
在您的示例“vev2qjeaun453sr4q4h3ais4ci”中,之前的“vev2qjeaun453sr4” 已经是有效的输入,它是一个 16 个字符的输入,并且 5 位 * 16 是 80 位,因此可以将其解析为 10 字节输出。现在让我们看看剩下的“q4h3ais4ci”, 10 char -> 5 * 10 = 50 位,前 40 位可以解码为 5 个字节,但最后 2 个字符“ci”导致 2 位余数
q | 4 | h | 3 | a | i | s | 4 | c | i 1 0 0 0 0|1 1 1 0 0|0 0 1 1 1|1 1 0 1 1|0 0 0 0 0|0 1 0 0 0|1 0 0 1 0|1 1 1 0 0|0 0 0 1 0|0 1 0 0 0 1 0 0 0 0 1 1 1|0 0 0 0 1 1 1 1|1 0 1 1 0 0 0 0|0 0 1 0 0 0 1 0|0 1 0 1 1 1 0 0|0 0 0 1 0 0 1 0|0 0 135 | 15 | 176 | 34 | 92 | 18 | c | i | = | = | = | = | = | = | 0 0 0 1 0|0 1 0 0 0|0 0 0 0 0|0 0 0 0 0|0 0 0 0 0|0 0 0 0 0|0 0 0 0 0|0 0 0 0 0| 0 0 0 1 0 0 1 0|0 0 0 0 0 0 0 0|0 0 0 0 0 0 0 0|0 0 0 0 0 0 0 0|0 0 0 0 0 0 0 0| 18 |
您需要添加 6 个内边距 5 % 8 的倍数的余数位为:
its bits are divisible every eight chars bitwise opinion byte opinion padding chars 1 char: 5 % 8 = 5 bit | 1 % 8 (char) = 1 -> 7 char 2 char: 10 % 8 = 2 bit | 2 % 8 (char) = 2 -> 6 char (this case "ci") 3 char: 15 % 8 = 7 bit | 3 % 8 (char) = 3 -> 5 char 4 char: 20 % 8 = 4 bit | 4 % 8 (char) = 4 -> 4 char 5 char: 25 % 8 = 1 bit | 5 % 8 (char) = 5 -> 3 char 6 char: 30 % 8 = 6 bit | 6 % 8 (char) = 6 -> 2 char 7 char: 35 % 8 = 3 bit | 7 % 8 (char) = 7 -> 2 char 8 char: 40 % 8 = 0 bit | 8 % 8 (char) = 8 -> 0 char
我修改了您的代码,输入“q4h3ais4ci”并填充 6 就可以了
func Base32Test() { // 8 char: 5 * 8 bits -> decodes to 5 bytes key, err := base32.StdEncoding.DecodeString("Q4H3AIS4") fmt.Println(key) if err != nil { fmt.Println("test 1, ", err) } else { fmt.Println("test 1 ok", key) } // 10 char: 5 * 10 bits -> decodes to 5 bytes and remaider (2 bits but the last 10 bits can not be decode) key, err = base32.StdEncoding.DecodeString("Q4H3AIS4CI") fmt.Println(key) if err != nil { fmt.Println("test 2, ", err) } else { fmt.Println("test 2 ok", key) } // padding key, err = base32.StdEncoding.DecodeString("Q4H3AIS4CI======") fmt.Println(key) if err != nil { fmt.Println("test 3, ", err) } else { fmt.Println("test 3 ok", key) } }
理论要掌握,实操不能落!以上关于《如何应对基于时间的一次性密码中的26字节秘密?》的详细介绍,大家都掌握了吧!如果想要继续提升自己的能力,那么就来关注golang学习网公众号吧!
-
502 收藏
-
502 收藏
-
501 收藏
-
501 收藏
-
501 收藏
-
139 收藏
-
204 收藏
-
325 收藏
-
477 收藏
-
486 收藏
-
439 收藏
-
357 收藏
-
352 收藏
-
101 收藏
-
440 收藏
-
212 收藏
-
143 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 立即学习 542次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 立即学习 508次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 立即学习 497次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 立即学习 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 立即学习 484次学习