基於TOTP演算法的Github兩步驗證2FA(雙因數)機制Python3.10實現

来源:https://www.cnblogs.com/v3ucn/archive/2023/09/29/17736955.html
-Advertisement-
Play Games

從今年(2023)三月份開始,Github開始強制用戶開啟兩步驗證2FA(雙因數)登錄驗證,毫無疑問,是出於安全層面的考慮,畢竟Github賬號一旦被盜,所有代碼倉庫都會毀於一旦,關於雙因數登錄的必要性請參見:別讓你的伺服器(vps)淪為肉雞(ssh暴力破解),密鑰驗證、雙向因數登錄值得擁有。 雙因 ...


從今年(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庫:

pip3 install pyotp

隨後編寫代碼生成當前時序的驗證碼:

import pyotp  
import time  
  
# 設置服務端密鑰  
secret_key = "Github服務端生成的密鑰(即二維碼)"  
  
# 使用密鑰和時間間隔(預設為 30 秒)創建一個 TOTP 對象  
totp = pyotp.TOTP(secret_key)  
  
# 生成當前的 OTP  
current_otp = totp.now()  
print(f"當前OTP: {current_otp}")

運行結果:

python -u "d:\jiyun\積雲\boo3_public\test_totp.py"  
當前OTP: 809888

可以看到根據密鑰我們生成了30秒以內有效期的驗證碼,隨後將該驗證碼填入頁面中的Verify the code from the app文本框即可。簡單方便,並不需要移動端的參與。

Golang1.21實現TOTP演算法

如果客戶端的語言是Golang,也可以輕鬆實現TOTP演算法,首先確保本機安裝Golang1.18以上的版本,這裡我們使用的是最新的Golang1.21:

PS C:\Users\zcxey> go version  
go version go1.21.1 windows/amd64

隨後通過go get安裝對應的totp包:

go get github.com/pquerna/otp  
go get github.com/pquerna/otp/totp

接著編寫入口代碼main.go文件:

package main  
  
import (  
	"encoding/base32"  
	"fmt"  
	"time"  
  
	"github.com/pquerna/otp"  
	"github.com/pquerna/otp/totp"  
)  
  
// Demo function, not used in main  
// Generates Passcode using a UTF-8 (not base32) secret and custom parameters  
func GeneratePassCode(utf8string string) string {  
	secret := base32.StdEncoding.EncodeToString([]byte(utf8string))  
	passcode, err := totp.GenerateCodeCustom(secret, time.Now(), totp.ValidateOpts{  
		Period:    30,  
		Skew:      1,  
		Digits:    otp.DigitsSix,  
		Algorithm: otp.AlgorithmSHA512,  
	})  
	if err != nil {  
		panic(err)  
	}  
	return passcode  
}  
  
func main() {  
  
	passcode := GeneratePassCode("Github官方生成的密鑰")  
  
	fmt.Print(passcode)  
  
}

這裡通過GeneratePassCode函數來生成驗證碼,預設有效期同樣是30秒,演算法基於otp.AlgorithmSHA512。

運行結果:

go run "d:\jiyun\積雲\boo3_public\main.go"  
692540

隨後同樣將該驗證碼填入頁面中的Verify the code from the app文本框即可。和Python不同的是,Golang直接編譯好以後可以在任意平臺直接運行,理論上要比Python要方便的多。

結語

總體而言,GitHub的雙因數登錄提供了更高的賬戶安全性,保護用戶免受未經授權的訪問和潛在的數據泄露。它是一種簡單而有效的安全措施,值得用戶採取以保護他們的GitHub賬戶和相關代碼資產,不過話說回來,Github官方力推收費的1Password軟體,應該是有一些利益上的綁定,但對於會代碼的我們來說,這都不算事兒。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 1. 複製切換 1.1. 複製是高可用性的基礎 1.1.1. 總是保留一份持續更新的副本數據,會讓災難恢復更簡單 1.2. “切換副本”(promoting a replica)和“故障切換”(failing over)是同義詞 1.2.1. 意味著源伺服器不再接收寫入,並將副本提升為新的源伺服器 ...
  • 1.d3.shuffle D3.shuffle() 方法用於將數組中的元素隨機排序。它使用 Fisher–Yates 洗牌演算法,該演算法是無偏的,具有最佳的漸近性能(線性時間和常數記憶體)。 D3.shuffle() 方法的語法如下: d3.shuffle(array, [start, end]) 其中 ...
  • 針對改動範圍大、影響面廣的需求,我通常會問上線了最壞情況是什麼?應急預案是什麼?你帶開關了嗎?。當然開關也是有成本的,接下來本篇跟大家一起交流下高頻發佈支撐下的功能開關技術理論與實踐結合的點點滴滴。 ...
  • 在前面幾天中,我們學習了Dart基礎語法、可迭代集合,它們是Flutter應用研發的基本功。今天,我們繼續學習Flutter應用另一個必須掌握知識點:非同步編程(即Future和async/await)。它類似於Java中的FutureTask、JavaScript中的Promise。它是後續Flut... ...
  • 一、直充內充(充值方式) 直充: 包裝套餐直接充值到上游API系統。【PID/Smart】 (如:支付寶、微信 話費/流量/語音/簡訊 等 充值系統)。 內充(套餐打包常見物聯卡系統功能): 套餐包裝 適用於不同類型套餐 如 流量、簡訊、語音 等。 (目前已完善流量邏輯) 二、套餐與計費產品 計費產 ...
  • QStandardItemModel 類作為標準模型,主打“類型通用”,前一篇水文中,老周還沒提到樹形結構的列表,本篇咱們就好好探討一下這貨。 還是老辦法,咱們先做示例,然後再聊知識點。下麵這個例子,使用 QTreeView 組件來顯示數據,使用的列表模型比較簡單,只有一列。 #include <Q ...
  • 本文主要涉及的問題:用ElementTree和XPath讀寫XML文件;解決ElementTree新增元素後再寫入格式不統一的問題;QTableWidget單元格設置控制項 ...
  • 第一題 下列代碼輸入什麼? public class Test { public static Test t1 = new Test(); { System.out.println("blockA"); } static { System.out.println("blockB"); } publi ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...