使用OTP动态令牌认证

为加强网络安全管理,降低帐号被冒用、盗用等带来的风险,有些系统启用OTP手机令牌双因子认证登录,即在原有用户名+密码认证的基础上,增加OTP动态口令认证。基于OTP算法的动态令牌加强了帐号的安全性,简单易用。

1、什么是OTP动态令牌认证?

OTP(One-Time Password)是一种基于共享密钥和时间戳算法的一次性密码。一般每30或60秒产生一个新口令,在客户端的动态口令和服务器的动态口令验证时,要求客户端和服务器能够保持一致的时间,计算的动态口令才能一致。
OTP算法是公开的,所以可以使用市面上任意一种支持OTP的客户端。

实现OTP的算法主要有两种:

  • HOTP(HMAC-Based One-Time Password Algorithm):基于 HMAC 的一次性密码。
  • TOTP(Time-Based One-Time Password Algorithm):基于时间戳的一次性密码。

2、怎么使用OTP动态口令?

2.1、OTP客户端

在手机的应用商店搜索:身份验证器,建议选择微软的Authenticator;或者在微信小程序中搜索:腾讯身份验证器。
图标样式

2.2、添加账号:基本原理是设置共享密钥(key),一般通过扫描二维码方式

二维码内容的格式如下:

otpauth://totp/{label}?secret={secret}&issuer={issuer}

label可以填写用户的名字,secret是经过 Base32 编码后的密钥,issuer是发行者

示例:

otpauth://totp/GitHub:monchickey?secret=EPKCRBXZHDPHOOZH&issuer=GitHub

前面的 otpauth 表示协议,totp 表示采用基于时间的一次性密码,GitHub 说明发行者是 GitHub,后面的格式就是:<用户名>?secret=<密钥 base32 值>&issuer=<发行者>。

包含中文的示例:
otpauth://totp/%E5%8…%B7%20123?secret=EPKCRBXZHDPHOOZH&issuer=%E9…%BF%9D

注:帐号对应的密钥是OTP令牌生成的唯一标识,请勿分享给他人。

2.3、打开身份验证器客户端,查看OTP动态口令

show code

3、示例

3.1、服务器端代码

class OtpServer(object):
    def __init__(self, key):
        if key:
            # base64.b64encode(key.encode('utf-8')).decode('utf-8')
            self.key = key
        else:
            self.key = None

    def verify(self, code):
        """
        验证动态口令
        """
        if self.key is None or code is None or len(code) < 0:
            return False
        try:
            otp = pyotp.TOTP(base64.b32encode(self.key.encode('utf-8')).decode('utf-8'))
            # 当前时间前后刷新周期数(验证码数),防止因网速、用户操作速度等导致的时间不一致
            return otp.verify(code, valid_window=5)
        except Exception as ex:
            return False

    def showqr(self):
        """
        生成二维码,用于OTP客户端扫描方式添加账号
        """
        if self.key is None:
            return ''
        try:
            otp = pyotp.TOTP(base64.b32encode(self.key.encode('utf-8')).decode('utf-8'))
            # otpauth://TYPE/LABEL?PARAMETERS
            uri = otp.provisioning_uri(name='MyTestTOTP', issuer_name='OTP令牌')
            return uri
        except Exception as ex:
            return False

3.2、客户端代码

class OtpClient(object):
    def __init__(self, key):
        if key:
            self.key = key
        else:
            self.key = None

    def create_totp(self):
        if self.key is None:
            return ''
        try:
            otp = pyotp.TOTP(base64.b32encode(self.key.encode('utf-8')).decode('utf-8'))
            code = otp.now()
            print(code)
            return code
        except Exception as ex:
            return None

3.3、模拟使用代码

客户端生成动态口令(微软身份验证器不让截屏,其实不用写代码),服务器端验证口令是否合法

if __name__ == '__main__':
    c = OtpClient('MyTestSecret')
    print(c.create_totp())
    s = OtpServer('MyTestSecret')
    code = input('input code:')
    print(s.verify(code))

run

结果为True说明验证通过

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值