TOTP时间密码算法

2024-04-03 960 0

双因子(多因子认证)

TOTP时间密码算法插图TOTP时间密码算法插图1

双因子认证多增加了一步一次性密码校验,更加安全。

有两种方式来生成一次性密码:

  1. SMS-based(基于短信):每次用户登录,都会从注册手机那里收到一条包含一次性密码的短信

  2. TOTP-based(基于时间):当开启双因子认证后,用户需要用特定的手机应用APP扫描二维码,这个应用程序会不断为用户生成一次性密码

TOTP工作流程

TOTP时间密码算法插图2

其中存在3个问题点:

  1. 应用程序如何用密钥(Secret Key)和计数器(Counter)生成一次性密码(One-Time -Password)

  2. 计数器如何更新?服务器如何保持跟踪计数器?

  3. 服务器怎么把密钥分享给应用程序?

第一个问题的答案就在HOTP算法中

HOTP又是什么呢

HMAC-Based One-Time Password. 该算法由IETF(互联网工程任务组)发布在RFC4226

使用方法:

  1. 从一个密钥和计数器生成HMAC哈希

hmac_result= HMAC-SHA-1(secret-key, counter)

  1. 通过上一步得到的输出是20个字节长的字符串,这个长字符串并不适合用作一次性密码,所以需要对它进行截断

int offset = hmac_result[19] & 0xf;
int bin_code = (hmac_result)[offset] & 0x7f << 24 | (hmac_result[offset+1] & 0xff) << 16 | (hmac_result[offset+2] & 0xff) << 8 | (hmac_result[offset+3] & 0xff) ;
finalOTP = (bin_code % (10 ^ numberOfDigitsRequiredInOTP));
SHA-1 HMAC bytes(Example)
-------------------------------------------------------------
| Byte Number                                               |
-------------------------------------------------------------
|00|01|02|03|04|05|06|07|08|09|10|11|12|13|14|15|16|17|18|19|
-------------------------------------------------------------
| Byte Value                                               |
-------------------------------------------------------------
|1f|86|98|69|0e|02|ca|16|61|85|50|ef|7f|19|da|8e|94|5b|55|5a|
-------------------------------***********----------------++|
  1. 最后一个字节,hmac_result[19]的16进制是0x5a,低4位bit是0xa

  2. offset 为字节0xa,十进制为10

  3. 从第10位开始算4个字节,得到0x50ef7f19,即动态二进制码,DBC1

  4. DBC1的 MSB 是0x50,所以DBC2=DBC2

  5. HOTP = DBC2 % 10^6=872921(6位动态码)

TOTP

Time-Based One-Time Password,发布在RFC6238by IETF.

TOTP使用HOTP算法获得一次性密码,两者不同的是TOTP使用Time时间参数替换counter(计数器),这样就解决了第二个问题。

与其初始化counter并跟踪它,不如使用time参数去获取OTP(一次性密码)。因此服务器和手机并须同步时间,这样就不用去跟踪counter了。

当然为了解决服务器和手机时区不同步的问题,使用Unix timestamp,这样就不用关注时区了。

但是Unix Time是以秒计算的,每秒都在变化,意味着生成的密码也将每秒变化,这样就不太好了。因此,需要设置一个significant interval间隔区间来更新密码。

Goole Authenticator APP每30秒更改一次密码

counter = currentUnixTime / 30

解决了第二个问题,我们接下来用QR code(二维码)来解决第三个同步密码问题。

QR code

虽然我们可以要求用户直接将密钥输入到他们的手机应用程序中,但出于安全原因,我们希望使密钥相当长,要求用户输入如此长的字符串不会是一种用户友好的体验。

现在手机都配置了摄像头,可以要求用户通过它来扫描QR code获取密码。我们要做的就说把密码转换成QR code展示给用户。

到现在3个问题都解决了,那么如何在程序中实现TOTP呢?

实现TOTP

有一些免费的手机程序(如Google Authenticator APP、Authy等),因此创建你自己的手机APP并不是必须的。

  1. 当用户请求开启双因子认证

  2. 服务器生成一个长度为20字节的密钥 secretKey = generateSecretKey(20)

  3. 为特定用户保存secret key到数据库中saveUserSecretKey(userId, secretKey)

  4. 把secret key转换成图片二维码image.qrCode = convertToQrCode(secretKey)

  5. 把图片二维码作为响应发送给用户responseresponse(qrCode)

  6. 用户扫描二维码获得secret key,用secret key、当前Unix time和HOTP算法,手机程序会生成动态密码

  7. 用户输入生成的动态密码

  8. 服务器从数据库中获取指定用户的secret key = getSecretKeyOfUser(userId)

  9. 如果服务器生成的动态密码和用户输入的相同,那么就可以为用户开启双因子认证。if (codeTypedByUser == getHOTP(secretKey, currentUnixTime / 30)) { enableTwoFactorAuthentication(userId);}

  10. 现在,在每次登录操作之后,我们需要检查这个特定用户是否启用了双因素身份验证。如果启用,那么我们要求在应用程序中显示一次性密码。如果输入的密码是正确的,那么只有这样才能对用户进行身份验证。

参考


4A评测 - 免责申明

本站提供的一切软件、教程和内容信息仅限用于学习和研究目的。

不得将上述内容用于商业或者非法用途,否则一切后果请用户自负。

本站信息来自网络,版权争议与本站无关。您必须在下载后的24个小时之内,从您的电脑或手机中彻底删除上述内容。

如果您喜欢该程序,请支持正版,购买注册,得到更好的正版服务。如有侵权请邮件与我们联系处理。敬请谅解!

程序来源网络,不确保不包含木马病毒等危险内容,请在确保安全的情况下或使用虚拟机使用。

侵权违规投诉邮箱:4ablog168#gmail.com(#换成@)

相关文章

webpack打包站点,js文件名批量获取思路
加密对抗靶场enctypt——labs通关
【论文速读】| 注意力是实现基于大语言模型的代码漏洞定位的关键
蓝队技术——Sysmon识别检测宏病毒
内网渗透学习|powershell上线cs
LLM attack中的API调用安全问题及靶场实践

发布评论