中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Google Authenticator TOTP原理和代碼示例

發布時間:2020-05-14 14:48:33 來源:億速云 閱讀:710 作者:Leah 欄目:開發技術

這篇文章主要介紹了Google Authenticator TOTP的原理以及使用代碼示例,具有一定借鑒價值,需要的朋友可以參考下。

話不多說,一起往下看吧。

一、 原理詳解(點擊圖片然后放大查看)
Google Authenticator TOTP原理和代碼示例

二、  驗證
1、下載Google谷歌身份驗證器。
2、通過Python 的qrcode和pyotp模塊生成二維碼。
Google Authenticator TOTP原理和代碼示例

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

# setup 1 : base32 secret
# 提示:Secret的長度最好不要超過32
Secret = 'userxiaosheng'

# Secret += '=' * (8-len(Secret)%8) # py3中base64模塊要求字符串必須為8的倍數,不足部分使用 = 補全
# 在查閱相關資料時,發現解決【可以將Key進行b3decode】的代碼都是這樣寫的(或者類似).
# 但是在生產環境中,為了給每個用戶生成不一樣的Key,我們必須通過各種算法,生成一個和用戶有關的字符串作為Key使用,
# 如果你使用的是 Secret += '=' * (8-len(Secret)%8) 這種方式解決b32decode問題,那么當Key中有數字時,
# b32decode將會報錯:binascii.Error: Non-base32 digit found,
# 通過測試,我找到了一段代替Secret += '=' * (8-len(Secret)%8)的代碼,所以在我這篇文章中,
# 將會使用Secret = base64.b32encode(s=Secret.encode('utf-8'))來代替類似Secret += '=' * (8-len(Secret)%8) 的代碼.

Secret = base64.b32encode(s=Secret.encode('utf-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、生成二維碼

import pyotp
from qrcode import QRCode
from qrcode import constants

Secret = 'userxiaosheng'
Secret = base64.b32encode(s=Secret.encode('utf-8'))
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的原理以及使用代碼示例就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果喜歡這篇文章,不如把它分享出去讓更多的人看到。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

晋州市| 阿勒泰市| 禄劝| 嵊州市| 岱山县| 屏山县| 华坪县| 马龙县| 河源市| 武城县| 依兰县| 久治县| 遂川县| 鲁甸县| 阿鲁科尔沁旗| 奇台县| 菏泽市| 汉中市| 大田县| 黔西县| 仲巴县| 北辰区| 讷河市| 黑河市| 临城县| 历史| 黄陵县| 镇原县| 衡东县| 定陶县| 深州市| 梁河县| 金乡县| 江陵县| 西藏| 信阳市| 紫云| 乐陵市| 黄龙县| 龙游县| 武陟县|