传统的用户名密码方式容易泄露,不安全。你说添加短信验证码是安全的。事实上,短信验证码也是不安全的,容易被截获和伪造。SIM卡也可以被克隆。曾出现过先伪造身份证,再申请同一个手机号的情况。把钱转走。于是就有了Two-factorauthentication,简称2FA,也就是双因素认证。最常见的是用户名和密码,加上一个动态代码。动态代码通常由便携式移动设备生成,例如USB屏蔽和手机。动态密码最常见的实现算法是一次性密码(OTP),这是一种基于时间的一次性密码。它是公认的可靠解决方案,已写入国际标准RFC6238。比如我们最常用的GoogleAuthenticator就是OTP。所以,了解了2FA,接下来你应该考虑的是如何让你用Python编写的网站实现2FA。其实这个轮子早就有了,就是PyOTP,结合自己的理解,分享一下它的用法。1.安装pip安装,不多说了。pip安装pyotp2。配对配对是移动设备与我们的网络服务器的配对。首先在服务端使用如下代码生成一个一次性密钥:>>>importpyotp>>>pyotp.random_base32()'BZ4TOJD4JWWJWPQBKP23FA55EMHA25Y2'>>>然后将这个密钥发送到手机(移动设备)中二维码扫描的形式,扫描后,手机上的应用程序保存密钥。3.验证接下来,可以使用以下逻辑在手机上生成动态密码。>>>totp=pyotp.TOTP('BZ4TOJD4JWWJWPQBKP23FA55EMHA25Y2')>>>totp.now()'941782'>>>现在,你有30秒的时间向服务器提交这个6位密码(在网页上输入)),服务器也使用相同的密钥和当前时间戳生成一个动态代码,并将其与用户提交的动态代码进行比较。只要两者不一致,就会验证失败,就是下面的逻辑。如果超过30秒(当然可以自定义30秒),也会失败:>>>totp=pyotp.TOTP('BZ4TOJD4JWWJWPQBKP23FA55EMHA25Y2')>>>totp.verify('941782')True>>>time.sleep(30)>>>totp.verify('941782')False除了使用基于时间的动态密码外,还可以使用基于计数的动态密码,逻辑如下:hotp=pyotp.HOTP('base32secret3232')hotp.at(0)#=>'260182'hotp.at(1)#=>'055283'hotp.at(1401)#=>'316439'#OTP通过counterhotp.verify('316439',1401)#=>Truehotp.verify('316439',1402)#=>False4.有没有在手机上开发的app?不用,我们直接使用现成的GoogleAuthenticator即可。如果你安装了GoogleAuthenticator,请点击?添加密钥,然后扫描下发的二维码生成动态码:然后可以执行以下代码,发现pyotp生成的动态码和GoogleAuthenticator输出的是一致的:importpyotptotp=pyotp.TOTP("JBSWY3DPEHPK3PXP")print("CurrentOTP:",totp.now())其实二维码的信息就是JBSWY3DPEHPK3PXP。这样我们使用GoogleAuthenticator生成动态密码,对网站进行二次验证,实现2FA。
