Google Authenticator TOTP原理詳解(以Python為例)
阿新 • • 發佈:2019-03-15
iss mes 博客 pack 驗證 ext 個數 blog googl 小生博客:http://xsboke.blog.51cto.com
如果有疑問,請點擊此處,然後發表評論交流,作者會及時回復(也可以直接在當前文章評論)。
-------謝謝您的參考,如有疑問,歡迎交流
一、 原理詳解(圖片可以點擊然後放大查看)
二、 驗證
1、下載Google谷歌身份驗證器。
2、通過Python 的qrcode和pyotp模塊生成二維碼。
3、然後使用下載的谷歌身份驗證器掃描生成的二維碼
如果沒有谷歌服務,則選擇輸入秘鑰,在賬戶明處填入name參數,在秘鑰處填入Secret即可。
4、對比手機上谷歌驗證器顯示的6位動態碼,你會發現,和【原理詳解】中代碼計算處的6位動態碼是一致的
三、 源碼
1、計算Google Authenticator 6位動態碼
#!/usr/bin/env python # -*- coding:utf-8 -*- # Google Authenticator工作原理 TOTP(Time-Based One-Time Password) import hmac import hashlib import base64 import struct import time import pyotp # setup 1 : base32 secret Secret = ‘userxiaosheng‘ Secret += ‘=‘ * (8-len(Secret)%8) # py3中base64模塊要求字符串必須為8的倍數,不足部分使用 = 補全 K = base64.b32decode(Secret,True) # setup 2 : get current timestamp # int(time.time()) // 30 到當前經歷了多少個30秒 C = struct.pack(">Q", int(time.time()) // 30) # 將間隔時間轉為big-endian(大端序)並且為長整型的字節 # setup 3 : start hmac-sha1 # hmac = SHA1(secret + SHA1(secret + input)) H = hmac.new(K,C,hashlib.sha1).digest() # 使用hmac sha1加密,並且以字節的方式取出 = b‘\x0f\x1a\xaeL\x0c\x8e\x19g\x8dv}\xde7\xbc\x95\xeal\xa3\xc1\xee‘ O = H[19] & 15 # bin(15)=00001111=0b1111 DynamicPasswd = str((struct.unpack(">I", H[O:O+4])[0] & 0x7fffffff) % 1000000) # struct.unpack(‘>I‘,h[o:o+4])[0] -- 轉為big-endian(大端序)並且不為負數的數字(整數),因為轉換完是一個數組,類似"(2828101188,)",所以需要[0]取出 # h[o:o+4] -- 取其中4個字節 o=10 則取索引分別為 10,11,12,13的字節 # & 0x7fffffff = 11111111 -- 與字節轉換的數字做與運算 # % 1000000 -- 得出的數字與1000000相除然後取余 TOTP = str(0) + str(DynamicPasswd) if len(DynamicPasswd) < 6 else DynamicPasswd # passwd = passwd if len(passwd) < 6 else str(0) + str(passwd) # 如果最後得出的6位數字,首位0,可能會只輸出5位數字,所以這裏進行一個判斷,如果是5位則加上首位的0 print(TOTP)
2、生成二維碼
from qrcode import QRCode from qrcode import constants Content = pyotp.totp.TOTP(Secret).provisioning_uri(name=‘xiaosheng‘, issuer_name="Verfiy Code") # 在真實環境中,name的參數應該是和Secret有關聯的,這樣我們才能為每個不同的用戶分別計算動態驗證碼. qr = QRCode(version=1, error_correction=constants.ERROR_CORRECT_L, box_size=6, border=4,) qr.add_data(Content) qr.make(fit=True) img = qr.make_image() img.save(‘./GoogleQR.png‘)
Google Authenticator TOTP原理詳解(以Python為例)