基於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
  • 當使用Autofac處理一個介面有多個實現的情況時,通常會使用鍵(key)進行區分或者通過IIndex索引註入,也可以通過IEnumerable集合獲取所有實例,以下是一個具體的例子,演示如何在Autofac中註冊多個實現,並通過構造函數註入獲取指定實現。 首先,確保你已經安裝了Autofac Nu ...
  • 本篇將分享Prometheus+Grafana的監控平臺搭建,並監控之前文章所搭建的主機&服務,分享日常使用的一些使用經驗本篇將配置常用服務的監控與面板配置:包括 MySQL,MongoDB,CLickHouse,Redis,RabbitMQ,Linux,Windows,Nginx,站點訪問監控,已... ...
  • 使用Aspirate可以將Aspire程式部署到Kubernetes 集群 工具安裝 dotnet tool install -g aspirate --prerelease 註意:Aspirate 正在開發中,該軟體包將作為預覽版進行版本控制,--prelease 選項將獲得最新的預覽版。 容器註 ...
  • 前言 本文要說的這種開發模式,這種模式並不是只有blazor支持,js中有一樣的方案next.js nuxt.js;blazor還有很多其它內容,本文近關註漸進式開發模式。 是的,前後端是主流,不過以下情況也許前後端分離並不是最好的選擇: 小公司,人員不多,利潤不高,創業階段能省則省 個人開發者,接 ...
  • 在.NET中,Microsoft.Extensions.Logging是一個靈活的日誌庫,它允許你將日誌信息記錄到各種不同的目標,包括資料庫。在這個示例中,我將詳細介紹如何使用Microsoft.Extensions.Logging將日誌保存到MySQL資料庫。我們將使用Entity Framewo ...
  • chatgpt介面開發筆記3: 語音識別介面 1.文本轉語音 1、瞭解介面參數 介面地址: POST https://api.openai.com/v1/audio/speech 下麵是介面文檔描述內容: 參數: { "model": "tts-1", "input": "你好,我是饒坤,我是ter ...
  • 前面兩篇文章主要是介紹瞭如何解決高併發情況下資源爭奪的問題。但是現實的應用場景中除了要解決資源爭奪問題,高併發的情況還需要解決更多問題,比如快速處理業務數據等, 本篇文章簡要羅列一下與之相關的更多技術細節。 1、非同步編程:使用async和await關鍵字進行非同步編程,這可以避免阻塞線程,提高程式的響 ...
  • 大家好,我是棧長。 Nacos 2.3.0 前幾天正式發佈了,新增了不少實用性的新功能,真是史上最強版本。 Nacos 2.3.0 還真是一個比較重要的大版本,因為它涉及了太多重大更新,今天棧長給大家來解讀下。 Nacos 先掃個盲: Nacos 一個用於構建雲原生應用的動態服務發現、配置管理和服務 ...
  • IDEA的遠程開發功能,可以將本地的編譯、構建、調試、運行等工作都放在遠程伺服器上執行,而本地僅運行客戶端軟體進行常規的開發操作即可,舊版本IDEA目前不支持該功能.,本例使用的是IDEA2023.2.5版本 下麵介紹如何在IDEA中設置遠程連接伺服器開發環境並結合Cpolar內網穿透工具實現無公網 ...
  • 本文解釋為啥會有響應式編程,為什麼它在開發者中不太受歡迎,以及引入 Java 虛擬線程後它可能最終會消失。 命令式風格編程一直深受開發者喜愛,如 if-then-else、while 迴圈、函數和代碼塊等結構使代碼易理解、調試,異常易追蹤。然而,像所有好的東西一樣,通常也有問題。這種編程風格導致線程 ...