- 參考資料在文末注明,如本文有錯(cuò)漏歡迎評(píng)論區(qū)指出??
目前很多應(yīng)用都逐步采用了雙因子認(rèn)證或者說MFA認(rèn)證方案,因此本文介紹一下背后的機(jī)制和TOTP算法原理。使用TOTP算法,只要滿足兩個(gè)條件:1)基于相同的密鑰;2)時(shí)鐘同步;只需要事先約定好密鑰,TOTP算法就可以保證校驗(yàn)段和被校驗(yàn)端具有相同的輸出。
OTP
在介紹 TOTP 算法前,先介紹一下 OTP 算法。OTP,One Time Password,又稱一次性口令、一次性密碼、動(dòng)態(tài)密碼、單次有效密碼。OTP 基于專門的算法每隔一定的時(shí)間間隔生成一個(gè)不可預(yù)測(cè)的隨機(jī)數(shù)字組合。OTP密碼有效期僅在一次會(huì)話或者交易過程中,因此不容易受到重放攻擊。OTP分為計(jì)次使用和計(jì)時(shí)使用兩種,計(jì)次使用的OTP產(chǎn)出后,可在不限時(shí)間內(nèi)使用。計(jì)時(shí)使用的 OTP 需要設(shè)置密碼有效時(shí)間,從30秒到兩分鐘不等,而 OTP 在進(jìn)行認(rèn)證之后即廢棄不用,下次認(rèn)證必須使用新的密碼,降低了不經(jīng)授權(quán)訪問限制資源可能性。
OTP密碼進(jìn)一步分為:
- HOTP:HMAC-based One-Time Password ,基于 HMAC 算法的一次性密碼。事件同步,通過某一特定的事件次序及相同的種子值作為輸入,通過 HASH 算法運(yùn)算出一致的密碼。
- TOTP:Time-based One-Time Password寫,基于時(shí)間戳算法的一次性密碼。 時(shí)間同步,基于客戶端的動(dòng)態(tài)口令和動(dòng)態(tài)口令驗(yàn)證服務(wù)器的時(shí)間比對(duì),一般每 30 秒產(chǎn)生一個(gè)新口令,要求客戶端和服務(wù)器能夠十分精確的保持正確的時(shí)鐘,客戶端和服務(wù)端基于時(shí)間計(jì)算的動(dòng)態(tài)口令才能一致。
計(jì)算 OTP 串的公式:OTP(K,C) = Truncate(HMAC-SHA-1(K,C))
K 表示秘鑰串;C 為隨機(jī)數(shù);HMAC-SHA-1 表示使用 SHA-1 做 HMAC;Truncate 表示怎么截取加密后的串,并取加密后串的哪些字段組成一個(gè)數(shù)字;
對(duì) HMAC-SHA-1 方式加密來說,Truncate 實(shí)現(xiàn)如下:
HMAC-SHA-1 加密后的長(zhǎng)度得到一個(gè) 20 字節(jié)的密串;取這個(gè) 20 字節(jié)的密串的最后一個(gè)字節(jié),取這字節(jié)的低 4 位,作為截取加密串的下標(biāo)偏移量;按照下標(biāo)偏移量開始,獲取4個(gè)字節(jié),按照大端方式(符合人類習(xí)慣的形式,比如 0x12 34 , 0x12 存放在低地址,大端即大端在前/高位在低地址存放的意思)組成一個(gè)整數(shù);截取這個(gè)整數(shù)的后 6 位或者 8 位轉(zhuǎn)成字符串返回。
TOTP 將其中的參數(shù) C 變成了由時(shí)間戳產(chǎn)生的數(shù)字:C = (T - T0) / X; T 表示當(dāng)前 Unix 時(shí)間戳:T0 一般取值為 0,也就是 1970 年 1 月 1 日。X 表示時(shí)間步數(shù),也就是說多長(zhǎng)時(shí)間產(chǎn)生一個(gè)動(dòng)態(tài)密碼,這個(gè)時(shí)間間隔就是時(shí)間步數(shù) X,系統(tǒng)默認(rèn)是 30 秒;
一個(gè)信息系統(tǒng)要集成 OTP 的認(rèn)證方式,需要完成以下的工作:
1、開發(fā)手機(jī)令牌
2、開發(fā)認(rèn)證的服務(wù)端,服務(wù)端需要完成令牌種子生成、令牌種子分發(fā)、動(dòng)態(tài)口令生成等功能。
3、在OTP認(rèn)證的服務(wù)端需要將業(yè)務(wù)系統(tǒng)的用戶與分發(fā)的令牌建立關(guān)聯(lián),這樣才能完成最終的登錄驗(yàn)證。
TOTP
TOTP 算法(Time-based One-time Password algorithm) 即基于具有時(shí)間戳計(jì)數(shù)器的 OTP。通過定義紀(jì)元(T0)的開始并以時(shí)間間隔(TI)為單位計(jì)數(shù),將當(dāng)前時(shí)間戳變?yōu)檎麛?shù)時(shí)間計(jì)數(shù)器(TC)。TOTP 實(shí)現(xiàn)可以使用 HMAC-SHA-256 或HMAC-SHA-512 (基于 SHA-256 或 SHA-512)函數(shù)來實(shí)現(xiàn),而不是 HOTP 計(jì)算中的 HMAC-SHA-1 函數(shù)【注:SHA1 存在 HASH 碰撞】。文章來源:http://www.zghlxwxcb.cn/news/detail-762722.html
TOTP 密碼生成過程文章來源地址http://www.zghlxwxcb.cn/news/detail-762722.html
- 初始化:用戶在服務(wù)提供商(如 Google 等)注冊(cè)賬戶時(shí),服務(wù)提供商(服務(wù)器)會(huì)為用戶生成一個(gè) 密鑰(Secret Key) 并保存在數(shù)據(jù)中。然后把這個(gè)密鑰會(huì)以某種方式(通常是 二維碼 )分享給用戶,用戶將其添加到(通過掃碼)自己的身份驗(yàn)證器應(yīng)用(如 Google Authenticator、Microsoft Authenticator)中。
- 生成 TOTP:身份驗(yàn)證器應(yīng)用會(huì)按照固定的時(shí)間間隔(常見的是 30 秒)使用 HMAC-SHA1 算法,使用當(dāng)前的時(shí)間戳和在初始化步驟中獲取的密鑰,生成一個(gè)新的一次性密碼,這個(gè)密碼通常是一個(gè) 6 位數(shù)字(但也可能更長(zhǎng)或更短)。
- 驗(yàn)證 TOTP:當(dāng)用戶嘗試登錄或執(zhí)行需要驗(yàn)證的操作時(shí),會(huì)被要求提供當(dāng)前的一次性密碼。用戶從自己的身份驗(yàn)證器應(yīng)用中獲取這個(gè)密碼,并輸入到服務(wù)提供商的網(wǎng)站或應(yīng)用中。服務(wù)提供商會(huì)使用同樣的算法和密鑰,以及當(dāng)前的時(shí)間戳,生成一個(gè)一次性密碼,并將其與用戶提供的密碼進(jìn)行比較。如果兩個(gè)密碼匹配,那么用戶的身份就被認(rèn)為已經(jīng)驗(yàn)證。
基于 Node.js 實(shí)現(xiàn)支持 Google 身份驗(yàn)證器的 TOTP 算法
import { Secret, TOTP } from 'otpauth';
// 生成密鑰
const secret = Secret.fromUTF8('your_secret_key');
// 生成TOTP實(shí)例
const totp = new TOTP({
secret,
issuer: 'Example',
label: 'alice@example.com'
});
// 生成token
const token = totp.generate(); // 30s
console.log('totp token:')
console.log(token);
// 驗(yàn)證token
const isValid = totp.validate({
token,
window: 1 // 一個(gè)窗口為一個(gè) period
});
if(isValid !== null) {
console.log('Valid token');
} else {
console.log('Invalid token');
}
// 轉(zhuǎn)成uri格式
const uri = totp.toString();
console.log(uri);
Reference
- Google身份驗(yàn)證器、基于時(shí)間的一次性密碼 (TOTP)算法
- OTP概念及實(shí)現(xiàn)原理簡(jiǎn)析
- 基于時(shí)間的一次性密碼 TOTP 詳解
- 密碼學(xué)I:密碼系統(tǒng)、OTP密碼和密碼的安全性
- 一文搞懂 OTP 雙因素認(rèn)證
- 使用 Golang 實(shí)現(xiàn)基于時(shí)間的一次性密碼 TOTP
- 基于 Node 實(shí)現(xiàn) TOTP:Otplib
到了這里,關(guān)于安全開發(fā):身份認(rèn)證方案之 Google 身份驗(yàn)證器和基于時(shí)間的一次性密碼 TOTP 算法的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!