翼度科技»论坛 编程开发 python 查看内容

基于TOTP算法的Github两步验证2FA(双因子)机制Python3.10实现

4

主题

4

帖子

12

积分

新手上路

Rank: 1

积分
12
从今年(2023)三月份开始,Github开始强制用户开启两步验证2FA(双因子)登录验证,毫无疑问,是出于安全层面的考虑,毕竟Github账号一旦被盗,所有代码仓库都会毁于一旦,关于双因子登录的必要性请参见:别让你的服务器(vps)沦为肉鸡(ssh暴力破解),密钥验证、双向因子登录值得拥有
双因子登录说白了就是通过第三方设备证明"你是你自己"的一个措施,Github官方推荐在移动端下载1Password、Authy、Microsoft Authenticator等APP来通过扫码进行验证,其实大可不必如此麻烦,本次我们通过Python/Golang代码来实现双因子登录验证。
TOTP算法

Time-based One-Time Password(TOTP)是一种基于时间的一次性密码算法,用于增强身份验证的安全性。
TOTP基于HMAC(Hash-based Message Authentication Code)算法和时间戳生成一次性密码。用户和服务器之间共享一个密钥,通常在初始化身份验证时交换。基于该密钥,服务器生成一个用于验证的初始值。
在每个时间步长(通常是30秒),基于当前时间戳和共享密钥,使用HMAC算法生成一个哈希值。然后,从哈希值中提取一个固定长度的动态密码。这个动态密码在设定的时间步长内有效,之后会自动失效。
用户在进行身份验证时,需要输入当前时间步长内生成的动态密码。服务器会使用相同的算法和共享密钥,验证用户提供的密码是否匹配。由于动态密码在时间步长过期后就会失效,即使被截获,也无法在下一个时间步长内重复使用。
TOTP广泛应用于双因素身份验证(2FA)和多因素身份验证(MFA)的实现中。通过结合用户的密码和每次生成的动态密码,TOTP提供了一层额外的安全保护,有效降低了密码被盗用或猜测的风险。
常见的TOTP应用包括Google Authenticator和Authy等身份验证应用程序,它们生成基于TOTP算法的动态密码,并与用户的在线账户相绑定,提供更安全的登录方式。
说白了,就是一个带生命周期的密钥,30秒之后这个密钥就会过期,客户端和服务端共享一个密钥,通过HMAC算法来验证密钥的合法性。
TOTP算法实现(Python3.10)

首先在服务端应该先生成一个密钥,该密钥在客户端和认证服务器之间共享。密钥可以是字符串,但Github官方把该密钥弄成了二维码,以方便用户在移动端扫码验证,打开Github账户,选择设置-》两步验证:

点击绿色按钮,选择开启两步验证。
此时系统会自动生成一个二维码,这就是我们共享的密钥:

该密钥的字符串形式可以通过点击setup key超链接来获取。
拿到系统密钥之后,我们安装基于Python的TOTP库:
  1. pip3 install pyotp
复制代码
随后编写代码生成当前时序的验证码:
  1. import pyotp  
  2. import time  
  3.   
  4. # 设置服务端密钥  
  5. secret_key = "Github服务端生成的密钥(即二维码)"  
  6.   
  7. # 使用密钥和时间间隔(默认为 30 秒)创建一个 TOTP 对象  
  8. totp = pyotp.TOTP(secret_key)  
  9.   
  10. # 生成当前的 OTP  
  11. current_otp = totp.now()  
  12. print(f"当前OTP: {current_otp}")
复制代码
运行结果:
  1. python -u "d:\jiyun\积云\boo3_public\test_totp.py"  
  2. 当前OTP: 809888
复制代码
可以看到根据密钥我们生成了30秒以内有效期的验证码,随后将该验证码填入页面中的Verify the code from the app文本框即可。简单方便,并不需要移动端的参与。
Golang1.21实现TOTP算法

如果客户端的语言是Golang,也可以轻松实现TOTP算法,首先确保本机安装Golang1.18以上的版本,这里我们使用的是最新的Golang1.21:
  1. PS C:\Users\zcxey> go version  
  2. go version go1.21.1 windows/amd64
复制代码
随后通过go get安装对应的totp包:
  1. go get github.com/pquerna/otp  
  2. go get github.com/pquerna/otp/totp
复制代码
接着编写入口代码main.go文件:
  1. package main  
  2.   
  3. import (  
  4.         "encoding/base32"  
  5.         "fmt"  
  6.         "time"  
  7.   
  8.         "github.com/pquerna/otp"  
  9.         "github.com/pquerna/otp/totp"  
  10. )  
  11.   
  12. // Demo function, not used in main  
  13. // Generates Passcode using a UTF-8 (not base32) secret and custom parameters  
  14. func GeneratePassCode(utf8string string) string {  
  15.         secret := base32.StdEncoding.EncodeToString([]byte(utf8string))  
  16.         passcode, err := totp.GenerateCodeCustom(secret, time.Now(), totp.ValidateOpts{  
  17.                 Period:    30,  
  18.                 Skew:      1,  
  19.                 Digits:    otp.DigitsSix,  
  20.                 Algorithm: otp.AlgorithmSHA512,  
  21.         })  
  22.         if err != nil {  
  23.                 panic(err)  
  24.         }  
  25.         return passcode  
  26. }  
  27.   
  28. func main() {  
  29.   
  30.         passcode := GeneratePassCode("Github官方生成的密钥")  
  31.   
  32.         fmt.Print(passcode)  
  33.   
  34. }
复制代码
这里通过GeneratePassCode函数来生成验证码,默认有效期同样是30秒,算法基于otp.AlgorithmSHA512。
运行结果:
  1. go run "d:\jiyun\积云\boo3_public\main.go"  
  2. 692540
复制代码
随后同样将该验证码填入页面中的Verify the code from the app文本框即可。和Python不同的是,Golang直接编译好以后可以在任意平台直接运行,理论上要比Python要方便的多。
结语

总体而言,GitHub的双因子登录提供了更高的账户安全性,保护用户免受未经授权的访问和潜在的数据泄露。它是一种简单而有效的安全措施,值得用户采取以保护他们的GitHub账户和相关代码资产,不过话说回来,Github官方力推收费的1Password软件,应该是有一些利益上的绑定,但对于会代码的我们来说,这都不算事儿。

来源:https://www.cnblogs.com/v3ucn/p/17736955.html
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x

举报 回复 使用道具