TOTP基本原理

TOTP是什么?

TOTP 是Time-based One-Time Password的簡寫,表示基于時間戳算法的一次性密碼。
是時間同步,基于客戶端的動態(tài)口令和動態(tài)口令驗證服務(wù)器的時間比對,一般每60秒,或30秒產(chǎn)生一個新口令,要求客戶端和服務(wù)器能夠十分精確的保持正確的時鐘,客戶端和服務(wù)端基于時間計算的動態(tài)口令才能一致。

適用場景

  • 服務(wù)器登錄動態(tài)密碼驗證
  • 公司VPN登錄雙因素驗證
  • 銀行轉(zhuǎn)賬動態(tài)密碼
  • 網(wǎng)銀、網(wǎng)絡(luò)游戲的實體動態(tài)口令牌
  • 等基于時間有效性驗證的應(yīng)用場景

TOTP的基本原理

TOTP計算公式

TOTP(K, TC) = Truncate(HMAC-SHA-1(K, TC))

K,密鑰串
HMAC-SHA-1, 表示使用SHA-1做HMAC(當(dāng)然也可以使用SHA-256等)
C,基于時間戳計算得出,通過定義紀(jì)元(T0)的開始并以時間間隔(TI)為單位計數(shù),將當(dāng)前時間戳變?yōu)檎麛?shù)時間計數(shù)器(TC)
Truncate,是一個函數(shù),用于截取加密后的字符串

TC的計算公式

TC = (T - T0) / T1;

T,當(dāng)前的時間戳
T0,起始時間,一般為0
T1,時間間隔,根據(jù)業(yè)務(wù)需要自定義

Truncate函數(shù)

  1. 取加密后的最后一個字節(jié)的的低4位,offset;
  2. 以offset開始取4個字節(jié),按照大端方式組成整數(shù),binary;
  3. 根據(jù)需要的長度對binary取模,opt
  4. 以字符串方式返回opt,并補足長度
h = hmac.new(self.key.encode(), msg, sha256).digest()
offset = h[len(h)-1] & 0xf
binary = (h[offset] & 0x7f) << 24
binary = binary | ((h[offset+1] & 0xff)<<16)
binary = binary | ((h[offset+2] & 0xff)<<8)
binary = binary | (h[offset+3] & 0xff)
otp = binary % (10 ** self.codeDigits)
return str(otp).rjust(self.codeDigits, '0')

Python實現(xiàn)

import binascii
import hmac
import time
from hashlib import sha256

class TOTP:
    
    def __init__(self, key, codeDigits):
        self.key = key
        self.codeDigits = codeDigits

    def truncate(self, time):
        time = time.rjust(16,'0')
        bigint = binascii.unhexlify(hex(int('10'+time, 16))[2:])
        msg = bigint[1:len(bigint)]
        h = hmac.new(self.key, msg, sha256).digest()
        offset = h[len(h)-1] & 0xf
        binary = (h[offset] & 0x7f) << 24
        binary = binary | ((h[offset+1] & 0xff)<<16)
        binary = binary | ((h[offset+2] & 0xff)<<8)
        binary = binary | (h[offset+3] & 0xff)
        otp = binary % (10 ** self.codeDigits)
        return str(otp).rjust(self.codeDigits, '0')

    def tc(self, ttl):
        return format(int(int(time.time())/int(ttl)),'x').upper()

上面的代碼就是我基于python3的實現(xiàn)(可以保存為totp.py),散列算法使用的是SHA-256,使用方式如下:

import totp
import base64

secretKey = base64.b32encode(b'My secret key')
t = totp.TOTP(secretKey, 4)
time = t.tc(60)    # 此處時間單位為秒
result=t.truncate(time)
print(result)

源碼可以從這里獲?。?br> github

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 該文章來自我的博客 摘要:本文根據(jù) RFC4226 和 RFC6238 文檔,詳細(xì)的介紹 HOTP 和 TOTP ...
    米車阿里閱讀 19,089評論 1 25
  • Swift1> Swift和OC的區(qū)別1.1> Swift沒有地址/指針的概念1.2> 泛型1.3> 類型嚴(yán)謹(jǐn) 對...
    cosWriter閱讀 11,665評論 1 32
  • 我最喜歡的時刻,莫過于在溫暖的陽光下,被陣陣清風(fēng)撫摸著臉頰,看著遠(yuǎn)處藍(lán)天白云和青山綠水,享受著片刻的歲月靜好。 ...
    燕竒旎閱讀 805評論 0 3
  • 大道之行,天下為公,為民既出,世界大同。 本章我們來具體闡述為民思想的內(nèi)容,在闡述為民思想的內(nèi)容之前,首先我們要明...
    為民思想閱讀 652評論 0 0
  • 前言平時總會使用工具eclipse的時候,感覺獲得或少的使用什么;提供一些總結(jié)和記錄。 基本使用 1. Eclip...
    weir_will閱讀 1,205評論 0 0

友情鏈接更多精彩內(nèi)容