TOTP 算法實現:雙因素認證的基石(C/C++代碼實現)

雙因素認證(Two-Factor Authentication, 2FA)扮演著至關重要的角色。它像是一道額外的防線,確保即便密碼被竊取,不法分子也難以輕易突破。在眾多雙因素認證技術中,基于時間的一次性密碼(Time-Based One-Time Password, TOTP)算法因其安全性高、使用便捷而受到廣泛應用。

TOTP算法是一種基于時間的一次性密碼生成算法,它的核心思想是利用時間作為變化的因子來生成動態的密碼。這種算法通常與用戶的個人信息結合使用,如用戶名或電子郵件地址,以及一個共享的秘密密鑰。這個秘密密鑰在用戶端和服務端預先共享,是生成正確OTP的關鍵。

TOTP是如何工作的呢?

讓我們通過一個簡單的比喻來理解其原理。想象一下,你有一本只屬于你和你的朋友的書,書中記載了一連串的故事,每個故事都有一個編號。每當你想要和朋友傳遞一個秘密信息時,你會查找當前日期對應的故事編號,并從中選取特定的段落來傳遞信息。在這個例子中,書就像是秘密密鑰,故事編號對應于時間戳,而傳遞的信息則是一次性密碼。

具體到TOTP算法,它使用了哈希函數(如SHA-1、SHA-256等)和時間戳。當用戶想要登錄系統時,用戶的設備會計算當前時間與預設時間步長的差值,然后將這個差值與共享的秘密密鑰一起輸入到哈希函數中。哈希函數處理后輸出一串較長的二進制數據,這串數據再經過模運算,得到一個較短的數字,這個數字就是OTP。用戶需要在規定的時間內將這個OTP輸入到驗證系統中,系統同樣會根據相同的秘密密鑰和時間差值計算出一個OTP,并與用戶提供的OTP進行比對,若兩者一致,則認證成功。

在實現上,TOTP算法需要考慮到時間同步的問題。由于網絡延遲或者設備時鐘不準確,可能導致用戶設備與服務器之間的時間有偏差。因此,TOTP算法通常會有一個時間窗口(如30秒),允許在這個時間范圍內的OTP都是有效的。

TOTP的優勢在于其安全性和用戶體驗。由于OTP是基于時間和共享秘密密鑰生成的,即使黑客截獲了某個時刻的OTP,它也無法在其他時間點使用,因為OTP每隔一段時間就會變化。此外,用戶可以不需要記憶復雜的密碼,只需擁有注冊時分配的密鑰(通常存儲在硬件令牌或軟件應用中),就可以輕松完成身份驗證。

TOTP的實現

Base32編碼與解碼

Base32編碼原理:
Base32編碼是一種將二進制數據轉換成32種可打印字符的編碼方式。它主要用于電子郵件和URL中傳輸二進制數據。Base32使用A-Z的大寫字母(不使用C, E, G, I, O, Q, U, V)和數字2-7來表示數據。每8位二進制數據可以編碼為5個Base32字符,這意味著編碼后的數據長度是原始數據的大約1.33倍。

實現Base32編碼:
編碼過程涉及將輸入的字節數據分成5位一組,每組轉換為對應的Base32字符。例如,如果輸入字節是0x9A,它對應于二進制的10011010,然后將其分成兩組:10011010。每組轉換為Base32字符,分別是SK

實現Base32解碼:
解碼過程與編碼相反,它將Base32字符轉換回原始的字節數據。解碼函數需要處理輸入的Base32字符串,跳過任何非Base32字符(如填充的等號),并將每個字符轉換回相應的5位二進制值。然后,這些值被重新組合成字節數據。

HMAC-SHA1算法

HMAC-SHA1基本概念:
HMAC(Hash-based Message Authentication Code)是一種消息認證碼,它使用哈希算法(如SHA-1)和密鑰來提供消息的完整性保護和認證。SHA-1是一種廣泛使用的加密哈希函數,它可以產生一個160位(20字節)的哈希值。

在TOTP中的應用:
在TOTP中,HMAC-SHA1用于生成一個基于密鑰、時間戳和算法參數的哈希值。這個哈希值隨后被用來生成6位數的一次性密碼。通過使用HMAC-SHA1,TOTP確保了即使密鑰被泄露,生成的密碼也難以被預測。

時間戳處理

時間戳的重要性:
TOTP算法依賴于時間戳來生成密碼,因此時間同步至關重要。如果客戶端和服務器之間的時間不同步,生成的密碼可能會無效。

確保時間同步:
為了確保時間同步,可以采取以下措施:

  • 使用網絡時間協議(NTP)來同步客戶端和服務器的時間。
  • 在用戶設備上設置時間校驗機制,確保時間偏差在可接受范圍內。

密碼生成邏輯

從HMAC-SHA1輸出中提取密碼:

  1. 使用HMAC-SHA1算法和當前時間戳生成一個20字節的哈希值。
  2. 對哈希值進行處理,提取出用于生成密碼的部分。具體來說,取哈希值的最后一個字節的最低4位作為索引,從這個位置開始讀取接下來的4個字節。
  3. 將這4個字節視為一個整數,然后對1000000取模,得到一個6位數的密碼。

生成6位數的密碼:

  • 將上述步驟得到的整數轉換為字符串形式,并確保它是一個6位數的密碼。如果需要,可以在前面補零。

TOTP 算法實現:雙因素認證的基石(C/C++代碼實現)

雙因素認證(2FA)作為一種增強安全性的方法應運而生。基于時間的一次性密碼(TOTP)是2FA的一種實現方式,它提供了一種動態生成、一次性使用的密碼,極大地提高了賬戶的安全性。下面實現類似Google Authenticator這樣的應用程序。


void hmac(void *dest,const void *key,uint32_t key_len,const void *msg,uint32_t msg_len,void (*hash)(char *dest, const char *str, int len),uint16_t block_size,uint16_t output_size
);
typedef struct
{uint32_t state[5];uint32_t count[2];unsigned char buffer[64];
} SHA1_CTX;void sha1_transform(uint32_t state[5], const unsigned char buffer[64]);
void sha1_init(SHA1_CTX * context);
void sha1_update(SHA1_CTX * context, const unsigned char *data, uint32_t len);
void sha1_final(unsigned char digest[20], SHA1_CTX * context);
void sha1(char *hash_out, const char *str, int len);
void bytes_array_reverse(uint8_t* bytes, int size);
int bytes_array_to_int(const uint8_t* bytes, int start, int end);
int base32_decode(const uint8_t *encoded, uint8_t *result, int bufSize);
char* str_upper(char* str);
char* str_pad_left(char* str, char pad, int len);
char* str_pad_right(char* str, char pad, int len);
int int_to_str(int i, char *buf, int buf_len);void get_2fa_code(char *secret, char code[7])
{char key[20];char hash[20];int key_len;uint64_t msg;str_upper(secret);  //轉換為大寫以獲得有效的Base32格式key_len = base32_decode((uint8_t*)secret, (uint8_t*)key, 20);           // 將機密解碼為字節數組msg = time(NULL) / 30;                                                  // TOTP是HOTP,種子為30秒。bytes_array_reverse((uint8_t*)&msg, 8);                                hmac(hash, key, key_len, (uint8_t*)&msg, 8, sha1, 64, 20);              // 生成hmac哈希int offset = hash[19] & 0xF;                                            int header = bytes_array_to_int((uint8_t*)hash, offset, offset + 4);    // 從偏移量開始截斷4個字節header = header & 0x7fffffff;                                           // 刪除最高有效位header = header % 1000000;                                              // 生成小于7位的余數int_to_str(header, code, 7);    // 將代碼轉換為字符串str_pad_left(code, '0', 6);     // 從左起用0填充代碼,直到代碼長度為6
}
int main(int argc, char **argv)
{
...if (argc != 2) {printf("./ga [secret]\n");return (0);}get_2fa_code(argv[1], code);printf("Code :\n%s\n", code);return (0);
}

運行結果:

If you need the complete source code, please add the WeChat number (c17865354792)

總結

Google Authenticator 的核心原理是利用共享密鑰和一個隨時間變化的因子來生成一次性密碼,從而實現第二因素的身份驗證。這種方法既方便又安全,因為它不需要額外的硬件令牌,只需要用戶的智能設備即可。此外,由于 OTP 是一次性的,并且隨時間變化,即使黑客截獲了當前的 OTP,也無法在未來的時間點使用它來冒充用戶。

We also undertake the development of program requirements here. If necessary, please follow the WeChat official account 【程序猿編碼】and contact me

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/16393.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/16393.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/16393.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

ubuntu/部分docker容器無法訪問https站點

ubuntu/部分docker容器無法訪問https站點 解決方案 解決方案 默認的系統內可能沒有安裝根證書,需要安裝一下 apt install ca-certificates如果官方源比較慢,可以換為國內源,但是不要使用https

【fastapi+mongodb】使用motor操作mongodb

上一篇文章,我們在電腦上安裝了mongodb數據庫。這篇文章,我們在fastapi后端使用motor操作mongodb 如果你還沒看過上一篇文章,鏈接在這里:【MongoDB】安裝與使用 安裝 motor motor 是一個用于操作 mongodb 數據庫的 python 庫&a…

計算機網絡 1

兩臺主機想通信,其實本質就是兩個文件的資源交換,但是長距離的通信,面臨的是很多的問題。這個時候需要通過一些方式來保證可靠性 什么是協議 這樣一個例子,我是住在農村,我讀高中了我需要去縣里面讀書。這個時候呢&…

VL15 優先編碼器Ⅰ

兩種思路 module encoder_83(input [7:0] I ,input EI ,output wire [2:0] Y ,output wire GS ,output wire EO );reg [4:0] temp1 ; always (*) begincasex({EI,I}) 9b0_xxxx_xxxx:begin temp1 5b000_0_0;…

冒泡排序和遞歸排序

目錄 一.冒泡排序 1.1概念: 1.2原理: 1.3簡單示例講解: 二.遞歸排序 1.1概念: 1.2原理: 1.3簡單示例講解: 一.冒泡排序 1.1概念: 冒泡排序是一種最基礎的交換排序。 通過反復交換相鄰…

Jupyter Lab 軟件安裝與使用

軟件簡介 Jupyter Lab 軟件是一個基于web 的交互式開發環境,集成了代碼編輯器、終端、文件管理器等功能,使得開發者可以在一個界面中完成各種任務。JupyterLab是Jupyter Notebook的全面升級,是一個集文本編輯器、終端以及各種個性化組件于一…

Java進階學習筆記29——Math、System、Runtime

Math: 代表的是數學,是一個工具類,里面提供的都是對數據進行操作的一些靜態方法。 示例代碼: package cn.ensourced1_math;public class MathTest {public static void main(String[] args) {// 目標:了解Math類提供…

那智不二越機器人維修案例分享

那智不二越工業機器人在工業范圍內廣泛應用于各種生產領域。其示教器作為人機交互的重要設備,常常需要定期維護和Nachi不二越機械手示教盒修理。 【Nachi不二越機器人示教器維修步驟】 1. 關閉電源 在進行任何那智不二越機器人維修操作之前,務必確保機器…

<商務世界>《75 微課堂<茶葉(1)-質量分級>》

1 中國茶葉分級 中國的10級標準是按照茶葉的外觀、香氣、滋味、湯色、葉底五個方面進行評分,分別用10分制進行評分,總分為50分,得分越高,茶葉的品質就越高。具體的分數和等級如下表所示: 2 每級的特點 茶葉的質量等級…

OceanBase SQL 診斷和調優實踐——【DBA從入門到實踐】第七期

數據庫作為絕大多數應用系統儲存數據的核心系統,在用戶系統需要訪問數據時,有著至關重要的作用。在這些交互中,SQL 語言是應用與數據庫系統之間“溝通”的橋梁,它負責將應用的指令傳達給數據庫。因此,SQL 的性能好壞直…

弱類型解析

php中 轉化為相同類型后比較 先判斷數據類型后比較數值 var_dump("asdf"0);#bool(true) var_dump("asdf"1);#bool(false) var_dump("0asdf"0);#bool(true) var_dump("1asdf"1);#bool(true)1、md5撞庫 例&#xff1a; <?php incl…

【智能算法應用】模擬退火算法求解多車型車輛路徑問題HFVRP

目錄 1.算法原理2.多車型車輛路徑HFVRP數學模型3.結果展示4.參考文獻5.代碼獲取 1.算法原理 模擬退火算法&#xff08;Simulated Annealing, SA&#xff09;是一種通用概率算法&#xff0c;用于在給定一個大的搜索空間內尋找問題的近似最優解。這種算法受到物理中退火過程的啟…

ffplay 使用文檔介紹

ffplay ffplay 是一個簡單的媒體播放器,它是 FFmpeg 項目的一部分。FFmpeg 是一個廣泛使用的多媒體框架,能夠解碼、編碼、轉碼、復用、解復用、流化、過濾和播放幾乎所有類型的媒體文件。 ffplay 主要用于測試和調試,因為它提供了一個命令行界面,可以方便地查看媒體文件的…

消息隊列拉模式下的訂閱關系不一致問題及解決方法

引言 在分布式系統中&#xff0c;消息隊列&#xff08;Message Queue&#xff0c;MQ&#xff09;是一種常用的組件&#xff0c;用于解耦生產者和消費者&#xff0c;緩解系統負載&#xff0c;提升系統的可靠性和可擴展性。在Java行業中&#xff0c;常見的消息隊列中間件有Apach…

煙囪ERP系統

一、煙囪系統定義 “煙囪式”系統&#xff0c;來自維基百科的解釋是&#xff1a;一種不能與其他系統進行有效協調工作的信息系統&#xff0c;又稱為孤島系統。 二、煙囪系統的案例 比如&#xff1a;就像以下一樣&#xff0c;各個系統之間是獨立的&#xff0c;所有對接是通過…

深度學習復盤與小實現

文章目錄 一、查漏補缺復盤1、python中zip()用法2、Tensor和tensor的區別3、計算圖中的迭代取數4、nn.Modlue及nn.Linear 源碼理解5、知識雜項思考列表6、KL散度初步理解 二、處理多維特征的輸入1、邏輯回歸模型流程2、Mini-Batch (N samples) 三、加載數據集1、Python 魔法方法…

【Android】安卓設備上的Fastboot模式詳解與使用指南

原諒把你帶走的雨天 在漸漸模糊的窗前 每個人最后都要說再見 原諒被你帶走的永遠 微笑著容易過一天 也許是我已經 老了一點 那些日子你會不會舍不得 思念就像關不緊的門 空氣里有幸福的灰塵 否則為何閉上眼睛的時候 又全都想起了 誰都別說 讓我一個人躲一躲 你的承諾 我竟然沒懷…

c++筆記3

優先隊列 普通的隊列是一種先進先出的數據結構&#xff0c;元素在隊列尾追加&#xff0c;而從隊列頭刪除。優先隊列是一種按照優先級決定出隊順序的數據結構&#xff0c;優先隊列中的每個元素被賦予級別&#xff0c;隊首元素的優先級最高。 例如&#xff1a;4入隊&#xff0c…

多文件和靜態/動態鏈接以及虛擬內存管理

多目標文件鏈接 //stack.c char stack[512]; int top -1; void push(char c){stack[top] c; }char pop(void){return stack[top--]; }int is_empty(void){return top 1; }// main.c #include <stdio.h> int a,b 1; int main(){ push(a); push(b); push(c); while(!is…