• python totp代码


    import time
    import datetime
    import math
    import hmac
    import base64
    import qrcode
    from PIL import Image
    from pyzbar import pyzbar
    from hashlib import sha1
    
    '''
    depend: qrcode,pillow,PIL,pyzbar
    
    '''
    
    class GoogleAuthenticator(object):
    
        def __init__(self,secretKey=None,digits=6,interval=30):
            self.secretKey = secretKey
            self.digits = digits
            self.interval = interval
    
        def __str_extend(self,old_str,length,extend_str):
            new_strs = None
            if len(old_str) < length:
                clen = length - len(old_str)
                s0 = ''.join([extend_str for i in range(clen)])
                new_strs = s0 + old_str
            elif len(old_str) == length:
                new_strs =  old_str
            return new_strs
    
        def __str_split(self,old_str,split_len,prefix='',suffix=''):
            array = []
            str_len = len(old_str)
            for i in range(0,str_len,4):
                if i + 4 < str_len:
                    array.append(prefix+old_str[i:i+4]+suffix)
                else:
                    array.append(prefix+old_str[i:str_len]+suffix)
            return array
    
        def __base32tohex(self,base32str):
            base32chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567"
            bits = ""
            for i in range(len(base32str)):
                char = str(base32str[i]).upper()
                idx = int(base32chars.index(char))
                bit = self.__str_extend(format(idx,'b'),5,'0')
                if bit is None:
                    raise Exception('bit={},len={}'.format(bit,len(bit)))
                bits += bit
            bitArray = self.__str_split(bits,4,'0b')
            hexstr = ''.join([format(int(i,2),'x') for i in bitArray])
            return hexstr
    
        def __get_HexSecret(self):
            hexstr = self.__base32tohex(self.secretKey)
            return hexstr
    
        def __byte_secret(self):
            missing_padding = len(self.secretKey) % 8
            if missing_padding != 0:
                self.secret += '=' * (8 - missing_padding)
            return base64.b32decode(self.secretKey, casefold=True)
    
        def __int_to_bytestring(self,i, padding=8):
            result = bytearray()
            while i != 0:
                result.append(i & 0xFF)
                i >>= 8
            return bytes(bytearray(reversed(result)).rjust(padding, b''))
    
        def __timecode(self, for_time):
            i = time.mktime(for_time.timetuple())
            return int(i / self.interval)
    
        def get_QR_url(self):
            base_url = "https://chart.googleapis.com/chart?chs=200x200&cht=qr&chl=200x200&chld=M|0&cht=qr&chl="
            QR_url = base_url + "otpauth://totp/user@host.com\%3Fsecret%3D" + self.secretKey
            return QR_url
    
        def get_QR_code(self):
            qr = qrcode.QRCode(version=1,error_correction=qrcode.constants.ERROR_CORRECT_L,box_size=10,border=4)
            data = self.get_QR_url()
            qr.add_data(data=data)
            qr.make(fit=True)
            img = qr.make_image(fill_color="green", back_color="white")
            img.show()
    
        def QR2url(self,QR_path):
            base_url = 'https://chart.googleapis.com/chart?chs=200x200&cht=qr&chl=200x200&chld=M|0&cht=qr&chl='
            ourl = pyzbar.decode(Image.open(QR_path), symbols=[pyzbar.ZBarSymbol.QRCODE])[0].data.decode("utf-8")
            QR_url = base_url + ourl
            return QR_url
    
        def QR2code(self,QR_path):
            QR_url = pyzbar.decode(Image.open(QR_path), symbols=[pyzbar.ZBarSymbol.QRCODE])[0].data.decode("utf-8")
            i = QR_url.find('\%3Fsecret%3D')
            l = len('\%3Fsecret%3D')
            if i == -1:
                i = QR_url.find('?secret=')
                l = len('?secret=')
            if i == -1:
            	raise Exception('QR is error')
            j = QR_url.find('?',i+1)
            if j == -1:
                j = QR_url.find('\%3F',i+1)
            if j == -1:
                sk = QR_url[i+l:]
            else:
                sk = QR_url[i+l:j]
            self.secretKey = sk
            timestamp = self.__timecode(datetime.datetime.now())
            str_code = self.generate_otp(timestamp)
            return str_code 
    
    
        def generate_otp(self,timestamp):
            key = self.secretKey
            hasher = hmac.new(self.__byte_secret(), self.__int_to_bytestring(timestamp), sha1)
            # print(hasher.hexdigest())
            hmac_hash = bytearray(hasher.digest())
            offset = hmac_hash[-1] & 0xf
            code = ((hmac_hash[offset] & 0x7f) << 24 |
                    (hmac_hash[offset + 1] & 0xff) << 16 |
                    (hmac_hash[offset + 2] & 0xff) << 8 |
                    (hmac_hash[offset + 3] & 0xff))
            str_code = str(code % 10 ** self.digits)
            while len(str_code) < self.digits:
                str_code = '0' + str_code
            return str_code
    
        def getTotp(self):
            timestamp = self.__timecode(datetime.datetime.now())
            str_code = self.generate_otp(timestamp)
            return str_code
    
        def at(self, for_time, counter_offset=0):
            if not isinstance(for_time, datetime.datetime):
                for_time = datetime.datetime.fromtimestamp(int(for_time))
            return self.generate_otp(self.timecode(for_time) + counter_offset)
    
        def verifyTotp(self,str_code):
            gTotp = self.getTotp()
            if gTotp == str_code:
                return True
            else:
                return False
    

      

  • 相关阅读:
    js的解析顺序 作用域 严格模式
    弹性盒模型----容器属性
    tomcat解压版的配置与使用
    将mysql中一行中的几个字段 转换成一列并从其他数据库中查对应的邮件信息
    电脑快捷键
    icell更改用户管理员
    kettle下载地址
    pycharm激活码
    leetcode-111. 二叉树最小深度 · Tree + 递归
    leetcode-102.层序遍历二叉树(正序)· BTree
  • 原文地址:https://www.cnblogs.com/navysummer/p/11943411.html
Copyright © 2020-2023  润新知