TOTP雙因素認證(2FA)php簡單實現

TOTP身份驗證的工作原理基于時間戳和密鑰。用戶需要在設置階段將密鑰與相應的身份驗證器進行綁定。通常,用戶會在需要使用TOTP動態驗證碼的APP或網站上獲得一個密鑰,然后將該密鑰添加到TOTP驗證器工具上。驗證器會根據當前的時間戳和密鑰生成一個一次性密碼(通常是6位數字),用戶需要將這個密碼輸入到需要驗證的系統中以完成身份驗證。

1、針對某個登錄用戶生成秘鑰

<?php
//生成32位的秘鑰
function generateSecret($length = 32) {$characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567'; // Base32 字符集$secret = '';for ($i = 0; $i < $length; $i++) {$secret .= $characters[random_int(0, strlen($characters) - 1)];}return $secret;
}$secret = generateSecret(); // 用戶的唯一 Secret
echo "Secret Key: $secret";

2、生成某個登錄用戶需要綁定到Authenticator的鏈接(二維碼形式顯示)

<?php
function generateQRCodeUrl($appName, $userEmail, $secret) {$issuer = urlencode($appName);$email = urlencode($userEmail);return "otpauth://totp/{$issuer}:{$email}?secret={$secret}&issuer={$issuer}";
}$appName = "xxx-test";//在app列表中顯示的名稱
$userEmail = "xxx.xxx@gmail.com";
$secret='4IRT6WN2RHWZHJ4ZOO2POMYB6W43FQ7G';
$qrCodeUrl = generateQRCodeUrl($appName, $userEmail, $secret);
echo $qrCodeUrl;//當前鏈接生成為二維碼的鏈接
//echo '<img src="' . $qrCodeUrl . '" alt="QR Code">';

3、登錄的時候驗證用戶輸入的code是否正確

<?php
/*** 生成動態驗證碼(驗證用)*/
function getOtp($secret, $timeSlice = null) {if ($timeSlice === null) {$timeSlice = floor(time() / 30); // 當前時間戳除以30秒}$secretKey = base32Decode($secret); // 解碼 Base32 密鑰$time = pack('N*', 0) . pack('N*', $timeSlice); // 將時間戳轉換為 64 位二進制// 使用 HMAC-SHA1 計算哈希值$hmac = hash_hmac('sha1', $time, $secretKey, true);// 截取動態偏移量$offset = ord(substr($hmac, -1)) & 0x0F;$binary = (ord($hmac[$offset]) & 0x7F) << 24 |(ord($hmac[$offset + 1]) & 0xFF) << 16 |(ord($hmac[$offset + 2]) & 0xFF) << 8 |(ord($hmac[$offset + 3]) & 0xFF);// 生成6位數字驗證碼return str_pad($binary % pow(10, 6), 6, '0', STR_PAD_LEFT);
}function base32Decode($base32) {$characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567';$base32 = strtoupper($base32);$bits = '';foreach (str_split($base32) as $char) {$bits .= str_pad(decbin(strpos($characters, $char)), 5, '0', STR_PAD_LEFT);}$bytes = '';foreach (str_split($bits, 8) as $byte) {$bytes .= chr(bindec($byte));}return $bytes;
}// $otp = getOtp($secret);
// echo "Generated OTP: $otp".PHP_EOL;
//驗證方法
function verifyOtp($secret, $userInput, $window = 1) {$timeSlice = floor(time() / 30);//TOTP 的核心是基于當前時間的30秒時間片。一個時間片的公式是for ($i = -$window; $i <= $window; $i++) {echo "OTP: " . getOtp($secret, $timeSlice + $i) . PHP_EOL;echo "$i:$window".PHP_EOL;if (getOtp($secret, $timeSlice + $i) === $userInput) {return true;}}return false;
}
//index.php 生成的secret
$secret='4IRT6WN2RHWZHJ4ZOO2POMYB6W43FQ7G';
$userInput = '927055'; // 用戶輸入的動態驗證碼
if (verifyOtp($secret, $userInput)) {echo "驗證通過!";
} else {echo "驗證碼錯誤,請重試。";
}

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

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

相關文章

day21——web自動化測試(3)Unittest+Selenium實戰小案例

【沒有所謂的運氣&#x1f36c;&#xff0c;只有絕對的努力?】 目錄 今日目標&#xff1a; 1、UnitTest框架 2、UnitTest 核心用例 2.1 TestCase 2.2 TestSuite 2.3 TestRunner 2.4 TestLoader 2.5 TestLoader 與 TestSuite的區別 2.6 Fixture 3、斷言 3.1 1230…

【Flink運行時架構】系統構架

SMP架構 數據處理系統的架構最簡單的實現方式就是單節點&#xff0c;但是隨著數據量的增大&#xff0c;為了使單節點的機器性能更加強大&#xff0c;需要增加CPU數量和加大內存來提高吞吐量。這就是所謂的SMP(Symmetrical Multi Processing,對稱多處理)架構。 但是這種架構帶來…

CountDownLatch應用舉例

定義 CountDownLatch是juc下的一個多線程鎖&#xff0c;下面是jdk對它的定義 A synchronization aid that allows one or more threads to wait until a set of operations being performed in other threads completes. 翻譯如下 一種同步輔助工具&#xff0c;允許一個或多個…

ADC(二):外部觸發

有關ADC的基礎知識請參考標準庫入門教程 ADC&#xff08;二&#xff09;&#xff1a;外部觸發 1、TIM1的CC1事件觸發ADC1DMA重裝載2、TIM3的TRGO事件(的更新事件)觸發ADC1DMA重裝載3、TIM3的TRGO事件(的捕獲事件)觸發ADC1DMA重裝載4、優化TIM3的TRGO事件(的捕獲事件)觸發ADC1D…

磁盤分區格式

MBR和GPT ?磁盤分區形式主要有兩種&#xff1a;MBR和GPT。?? MBR&#xff08;Master Boot Record&#xff09; MBR是一種較舊的分區形式&#xff0c;首次引入于1983年的IBM PC DOS 2.0。它位于驅動器的第一個扇區&#xff0c;包含460字節的引導代碼、64字節的磁盤分區表和…

幾個支持用戶名密碼的代理鏈工具: glider, gost, proxychains+microsocks

幾個支持用戶名密碼的代理鏈工具: glider, gost, proxychainsmicrosocks gost -L:7777 -Fsocks5://192.168.2.20:7575 -Fsocks5://user:passwd1.1.1.1:10086 -Dgost&#xff1a;(https://github.com/ginuerzh/gost) 參考 https://www.quakemachinex.com/blog/279.html

量子退火與機器學習(1):少量數據求解未知QUBO矩陣,以少見多

文章目錄 前言ー、復習QUBO&#xff1a;中藥配伍的復雜性1.QUBO 的介入&#xff1a;尋找最佳藥材組合 二、難題&#xff1a;QUBO矩陣未知的問題1.為什么這么難&#xff1f; 三、稀疏建模(Sparse Modeling)1. 欠定系統中的稀疏解2. L1和L2的選擇&#xff1a; 三、壓縮感知算法(C…

【連續學習之SSL算法】2018年論文Selfless sequential learning

1 介紹 年份&#xff1a;2018 期刊&#xff1a; arXiv preprint Aljundi R, Rohrbach M, Tuytelaars T. Selfless sequential learning[J]. arXiv preprint arXiv:1806.05421, 2018. 本文提出了一種名為SLNID&#xff08;Sparse coding through Local Neural Inhibition and…

關于SNAT、DNAT及浮動地址

SNAT、DNAT SNAT、DNAT就是實現代理的功能。 SNAT 類似于客戶端代理&#xff1a;內網主機通過共享公網 IP 地址訪問外部服務。DNAT 類似于服務端代理&#xff1a;外部請求通過公網 IP 轉發到內網主機上的服務。 沒有大網地址的內部主機想要作為客戶端訪問外部網絡&#xff08;主…

結構方程模型【SEM】:嵌套分層數據及數據分組分析

結構方程模型&#xff08;System of Equations Model&#xff0c;簡稱SEM&#xff09;&#xff0c;在生態學和環境科學中通常指的是一組描述生態系統中能量、物質和信息流動的數學方程。這些方程可以是確定性的&#xff0c;也可以是隨機的&#xff0c;它們共同構成了一個模型&a…

hot100_56. 合并區間

以數組 intervals 表示若干個區間的集合&#xff0c;其中單個區間為 intervals[i] [starti, endi] 。 請你合并所有重疊的區間&#xff0c;并返回 一個不重疊的區間數組&#xff0c;該數組需恰好覆蓋輸入中的所有區間 。數據結構 二維鏈表存儲每個區間 方法 先對每個區間的…

Python大數據:基于Python的王者榮耀戰隊數據分析系統的設計與實現

系統展示 比賽信息管理 看板展示 系統管理 摘要 本文使用Python與MYSQL技術搭建了一個王者榮耀戰隊的數據分析系統。對用戶提出的功能進行合理分析&#xff0c;然后搭建開發平臺以及配置計算機軟硬件&#xff1b;通過對數據流圖以及系統結構的設計&#xff0c;創建相應的數據…

兩分鐘解決:vscode卡在設置SSH主機,VS Code-正在本地初始化VSCode服務器

問題原因 remote-ssh還是有一些bug的&#xff0c;在跟新之后可能會一直加載初始化SSH主機解決方案 1.打開終端2.登錄鏈接vscode的賬號&#xff0c;到家目錄下3.找到 .vscode-server文件,刪掉這個文件4.重啟 vscode 就沒問題了

深入理解與優化Java二維數組:從定義到性能提升的全面指南

1. 定義和初始化二維數組 在Java中&#xff0c;二維數組可以看作是數組的數組。你可以將它想象成一個矩陣或表格&#xff0c;每個元素是一個數組。 1.1 定義二維數組 二維數組的定義語法如下&#xff1a; datatype[][] arrayName;datatype 是數組元素的數據類型。arrayName…

day26 文件io

函數接口 1 .open和close 文件描述符&#xff1a;系統為用open打開的文件分配的標識符 非負的整形數據 0-1023 最小未被使用原則 使用完時及時釋放&#xff0c;避免文件描述符溢出 文件描述溢出就是文件使用完沒有及時關閉文件 int open(const char *pathname, int flags); /…

Java Stream流詳解——串行版

Stream流——串行版 ? Stream流是java8引入的特性&#xff0c;極大的方便了我們對于程序內數據的操作&#xff0c;提高了性能。通過函數式編程解決復雜問題。 1.BaseStream<T,S extense BaseStream<T,S>> ? 他是流處理的基石概念&#xff0c;重點不在于這個接…

el-backtop(返回頂部)

案例&#xff1a; <el-backtop target".app-main"><svg-icon icon-class"backtop" size"24px" /></el-backtop>

探秘“香水的 ChatGPT”:AI 開啟嗅覺奇幻之旅!

你沒有看錯&#xff0c;AI也能聞到味道了&#xff01;這是一家名為Osmo公司公布的信息&#xff0c;他們成功創造出了由AI生成的李子味道&#xff0c;快跟著小編一探究竟吧~ 【圖片來源于網絡&#xff0c;侵刪】 Osmo公司的這項技術&#xff0c;通過分析香味的化學成分和人類嗅…

Vue3入門(9)

1. 【 replace屬性】 作用&#xff1a;控制路由跳轉時操作瀏覽器歷史記錄的模式。 瀏覽器的歷史記錄有兩種寫入方式&#xff1a;分別為push和replace&#xff1a; - push是追加歷史記錄&#xff08;默認值&#xff09;。 - replace是替換當前記錄。 . 開啟replace模式&#xff…

第十九章 C++ 日期 時間

C 日期 & 時間 C 標準庫沒有提供所謂的日期類型。C 繼承了 C 語言用于日期和時間操作的結構和函數。為了使用日期和時間相關的函數和結構&#xff0c;需要在 C 程序中引用 <ctime> 頭文件。 有四個與時間相關的類型&#xff1a;clock_t、time_t、size_t 和 tm。類型…