一、配景
随着关注数据安全的意识逐步提升,很多站点都开始强制用户不止利用用户名+密码的形式进行登录,还会逐步引导用户开启2FA多因子验证。 Github就已经强制用户利用2FA多因子验证进行账号的登录,现在阿里云、腾讯云等也逐步往这个方向发展。
那什么是2FA多因子验证呢?
2FA,2 Factor Authentication,双因子验证/双因素验证,是一种安全密码验证方式。区别于传统的密码验证,由于传统的密码验证是由一组静态信息组成,如:字符、图像、手势等,很容易被获取,相对不安全。2FA是基于时间、历史长度、实物(光荣卡、SMS手机、令牌、指纹)等天然变量结合一定的加密算法组合出一组动态密码,一般每60秒刷新一次。不容易被获取和破解,相对安全。
说简单点,我们传统利用用户名+密码的形式进行登录不够安全,假如你的密码泄漏了,那么别人也能登录你的账号进行非法操作。 但是这种2FA认证呢,会在验证账号+密码通过之后,还会进行一次认证。 这一次认证,会给你一个30s大概60s之内的一个token大概验证码,这个验证码是动态的,必须在30s大概60s之内利用,否则立马就失效。并且这些token都是一次性的。
那假设你泄漏密码的之后,由于另有一层2FA的验证方式,那么由于黑客无法拿到2FA动态一次性密码,从而无法进行最后的验证操作,导致登录步调无法继续得以进行,包管了账号的安全性。
那有人就问了,我这种完全可以通过发送短信验证码大概邮箱验证码的方式实现二次认证啊。2FA认证和短信验证码又有什么区别呢? 按照我的理解两者优缺点如下:
【2FA验证方式】
长处:
1、动态令牌,每隔30s大概60s天生动态令牌,在不泄漏秘钥的情况下,黑客依靠穷举的方法,无法短时间内进行破解
2、站点无须增加短信开销资本,由于动态令牌是在客户端产生的,无需向用户发送
3、用户无需预留手机号等信息,用户注册也不一定需要手机号,低沉用户填写个人信息门槛负担,用户无需担心手机号等信息泄漏(但是,国内都要实行手机号、实名制等,这个是政策标题,而非技术大概产物标题)
缺点:
1、刚开始的利用门槛相对短信复杂,由于需要下载如Google authenticator等支持OTP认证协议动态天生口令的APP大概工具
【短信验证方式】
长处:
1、简单易用,用户利用门槛低。很简单,收到短信验证码填写即可
缺点:
1、站点需要花费发送短信的资本,需要向短信运营商付出费用,假如用户量很大、短信量也会很大,资本是需要考虑的
二、利用流程
利用Github登录进行举例
1、站点设置开启2FA多因子验证功能
2、利用站点提供的APP大概下载Google authenticator扫描2FA二维码
我会在手机上下载这个APP: Google authenticator
其实另有很多类似这APP, 就是一个辨认OTP协议、并且天生动态一次性口令的客户端工具。
3、每次要填写2FA验证码,检察动态口令,输入口令
进入APP,扫描站点提供的2FA二维码,这个二维码其实包含了你的一个秘钥,以是这个二维码不能泄漏出去,泄漏出去和你的账号密码是一个道理。
客户端会根据你的秘钥和时间戳,按照OTP协议的标准天生6位数字的一次性令牌,有用时间是30s.
需要输入2FA口令的时候,在有用期时间内输入天生的口令/验证码即可通过认证。 二维码扫描只是一种方便的方式,二维码里面包含了秘钥的信息,以是没有二维码的时候,也支持手填秘钥的方式。
三、实现原理
2FA的一次性密码验证方式,其实原理很简单。 服务端会先给客户端一个秘钥key(不能泄漏), 客户端和服务端会利用同一套秘钥key, 这个key一般是会通过base32进行编码。
然后,客户端和服务端根据相同的密钥,以及时间戳(时间戳偶然间范围,比方30s, 防止客户端、服务端时间弊端,导致无法进行比力验证)。 2FA天生一次性密码和时间关系很大,时间差距太大,会导致双方产生的令牌/一次性密码无法比力通过。
客户端工具,无论是哪个APP, 其实本质很简单,就是拿着你的秘钥key(可以通过二维码扫描出来,也可以进行手动填写的方式), 然后根据时间戳+秘钥的方式,按照OTP密码天生标准天生令牌。
客户端通报令牌到后端,后端也利用同一套算法、秘钥、时间戳等天生令牌,两者令牌假如对比成功,那么验证通过,否则验证失败。
流程图如下:
四、代码模仿2FA认证过程
以下代码利用python进行实例,其它编程语言也是一样的,都会有一些开源的客户端SDK.
1、服务端天生约定的2FA密钥,客户端需要进行保存,不能泄漏
- import pyotp
- import base64
- #实际秘钥信息
- raw_secret_key = "rocky"
- #需要进行base32编码,最后给用户的是base32编码之后的字符串
- secret_key = base64.b32encode(raw_secret_key.encode(encoding="utf-8"))
- print(f"秘钥信息: {secret_key.decode(encoding='utf-8')}")
复制代码 最简单的就是直接输出密钥,运行如下:
这个密钥就是客户需要纪录下来,且不能泄漏的。 为了低沉用户的利用门槛和增加用户体验,我们还可以天生二维码的方式。
记着这个密钥信息: OJXWG23Z
2、otpauth协议内容
OTPAuth 是一种用于设置一次性密码(One-Time Password, OTP)应用的协议。它允许通过扫描二维码或手动输入URL的方式设置基于时间的一次性密码(TOTP)或基于计数器的一次性密码(HOTP)。这种设置信息通常包含了天生OTP所需的全部参数,如密钥、算法范例、数字长度等。
一个典范的 OTPAuth URL 看起来像这样:
- otpauth://TYPE/LABEL?PARAMETERS
复制代码 TYPE 表现 OTP 的范例,可以是 totp 或 hotp。
LABEL 通常是用户可见的名字大概标识符,用来辨认这个 OTP 设置。它一般格式化为 issuer:accountName,其中 issuer 是服务提供商的名字,而 accountName 是用户的账户名。
PARAMETERS 包含了一系列键值对形式的参数,用以提供天生 OTP 所需的信息。这些参数大概包括但不限于:
secret: 这个密钥是[必须],用于天生 OTP。它是 Base32 编码的字符串。
issuer: 发行者名称[可选],这在 LABEL 中已经提供了,但是在这里重复是为了确保兼容性和正确表现。
algorithm: 指定哈希算法[可选],默认是 SHA1。其他支持的算法包括 SHA256 和 SHA512。
digits: 指定 OTP 的位数[可选],默认是6位,但也可以设置为8位。
period: 对于 TOTP 范例来说[可选],这是指更新 OTP 的时间隔断,默认是30秒。
counter: 对于 HOTP 范例来说[可选],这是当前的计数值。每利用一次 OTP,这个值会递增。
比方,一个完整的 TOTP URL 大概看起来像这样
- otpauth://totp/Example:alice@google.com?secret=JBSWY3DPEHPK3PXP&issuer=Example&algorithm=SHA1&digits=6&period=30
复制代码 1、首先是otpauth协议名称,类比http协议的格式, 协议名称://
2、totp是固定的
3、Example是服务的名称
4、alice@google.com是账号名
5、secret=后面就是秘钥
6、issuer颁发者信息, 以及后面是各个参数信息。和HTTP的GET参数类似
Google authenticator等工具,扫描二维的原理就是根据otpauth协议的标准剖析二维码的URL信息,拿到密钥信息用来天生一次性令牌.
3、根据天生的密钥,构造otpauth URL地址,天生二维码
- otpauth://totp/blog:rocky@google.com?secret=OJXWG23Z&issuer=rocky
复制代码 可以利用python大概客户端天生二维码图片,我为了方便直接chrome插件【草料二维码】天生即可.
4、利用客户端扫描二维码,2FA天生动态令牌
可以看到我扫描了二维码之后,新增了一个账号信息,可以及时天生动态口令, 并且口令存在30s的过期时间,过期会自动天生新的令牌:
5、模仿服务端解码过程
- import pyotp
- #约定的密钥
- secret_key = "OJXWG23Z"
- totp = pyotp.TOTP(secret_key)
- #用户输入的动态口令
- user_input_code = input("请输入您的TOTP码进行验证: ")
- if totp.verify(user_input_code):
- print("TOTP码验证成功")
- else:
- print("TOTP码验证失败")
复制代码 五、总结
2FA确实能增加我们的安全性,但是用起来门槛确实比力高,对于很多互联网小白望而却步。以是这种场景在数据不是很敏感的情况下,很少有产物强行推这种验证方式。 宁愿利用短信的方式,能低沉用户的利用门槛以及带来良好的产物体验。
但是随着数据安全的器重,预计以后针对银行、金融、以及如云计算服务公司等等,也会渐渐推广。
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |