自从用过谷歌(Google Authenticator)二次验证算法,我就充满了好奇感,同时觉得这种方式非常酷。
一个纯离线的设备,就能生成用于网络验证的验证码。
这就可以让我们完全摆脱都某些东西的依赖。
虽然这个算法是用于二次验证,但是我觉得用于一次验证也很酷啊。
我已经讨厌透了手机验证码,完全受限于移动运营商。
很多应用没法收验证码,懂的都懂。
出于对这个算法的好奇,一直想要研究一下,终于抽空问了下GPT4。
写个笔记!
算法原理
谷歌二次验证(Google Authenticator)使用的是基于时间的一次性密码(TOTP, Time-Based One-Time Password)算法,这是一种广泛应用于两步验证过程的算法。TOTP的工作原理可以概括如下:
-
HMAC算法:TOTP是基于HMAC(Hash-Based Message Authentication Code)算法构建的,它结合了一个共享的秘密密钥和当前时间来生成一次性密码。
-
共享密钥:在设置Google Authenticator时,用户的设备和验证服务器之间会共享一个密钥。这个密钥是安全存储的,并且对于每个账户是唯一的。
-
时间作为参数:TOTP算法使用当前的时间作为变化因素。时间通常被分割成固定的时间片段(例如,每30秒一个片段)。
-
生成一次性密码:
- 首先,当前时间被转换为一个计数器值,这通常是自Unix纪元(1970年1月1日)以来的30秒间隔数。
- 然后,使用HMAC算法结合这个计数器值和共享密钥来生成一个哈希值。
- 最后,从这个哈希值中提取一个较短的数字序列,通常是6到8位数,作为一次性密码。
-
验证一次性密码:当用户输入一次性密码时,验证服务器也会独立生成一个密码,使用相同的共享密钥和当前时间。如果两者匹配,验证成功。
安全性
-
密码的动态生成:由于密码是基于当前时间生成的,它每30秒就会变化一次,因此即使密码被截获,也很难被再次利用。
-
无需网络:生成密码不依赖于网络连接,因为它基于时间和共享密钥,这增加了安全性和可用性。
-
共享密钥的安全性:只要这个密钥保持安全,生成的密码就很难被预测或重现。
谷歌二次验证的实现提供了一种相对简单且安全的方法来增加账户的安全性,有效地降低了账户被非授权访问的风险。
代码实现
本来以为需要自己写很多代码才能实现,其实已经有专门的依赖包。下面就以Python为例,记录下验证专用包的使用方法!
为了实现这个验证功能,可以使用pyotp
库,这是一个Python库,用于实现TOTP和HOTP算法。以下是如何使用pyotp
来创建一个简单的客户端生成器和服务端验证器的步骤:
安装依赖包
首先,你需要安装pyotp
库。可以使用pip进行安装:
pip install pyotp
生成秘钥
import pyotp
# 生成一个秘密密钥,这个应该是共享给用户的,并且安全存储
secret = pyotp.random_base32()
print("Secret:", secret)
这个秘钥,服务器端存一份,客户端存一份。
客户端:生成一次性密码
# 实例化TOTP对象
totp = pyotp.TOTP(secret)
# 生成当前的一次性密码
current_otp = totp.now()
print("Current OTP:", current_otp)
根据秘钥生成一次性密码(验证码)
服务端:验证一次性密码
# 假设这是从客户端接收到的一次性密码
received_otp = input("Enter the OTP: ")
# 使用相同的秘密密钥创建TOTP对象
totp = pyotp.TOTP(secret)
# 验证一次性密码
if totp.verify(received_otp):
print("The OTP is valid.")
else:
print("The OTP is invalid.")
在服务端,你将使用相同的秘密密钥来验证客户端提供的一次性密码是否正确。
注意事项
- 秘密密钥必须安全地存储和共享。在实际应用中,应该通过安全的通信方式将秘密密钥发送给用户,并在服务端安全地存储。
- 由于时间同步的原因,确保客户端和服务端的时间设置是准确的。
pyotp
提供的一次性密码默认每30秒变化一次,这是TOTP标准的一部分。
当然,这只是一个基本的示例,简单展示下使用pyotp
库来实现一次性密码的生成和验证。在实际的生产环境中,还需要考虑更多的问题,来保障这个过程的安全可靠。
验证类
写一个简单类来做验证码生成和验证处理。
import pyotp
import os
class PyOTPApplication:
def __init__(self, secret_file='secret.key'):
self.secret_file = secret_file
self.secret = self.load_or_generate_secret()
def load_or_generate_secret(self):
"""加载或生成新的秘钥,并保存到本地文件"""
if os.path.exists(self.secret_file):
with open(self.secret_file, 'r') as file:
return file.read().strip()
else:
secret = pyotp.random_base32()
with open(self.secret_file, 'w') as file:
file.write(secret)
return secret
def generate_otp(self):
"""生成当前的一次性密码"""
totp = pyotp.TOTP(self.secret)
return totp.now()
def verify_otp(self, otp):
"""验证给定的一次性密码"""
totp = pyotp.TOTP(self.secret)
return totp.verify(otp)
# 使用示例
app = PyOTPApplication()
# 生成一次性密码
otp = app.generate_otp()
print("Generated OTP:", otp)
# 验证一次性密码
valid = app.verify_otp(otp)
print("Is OTP valid?", valid)
-
秘钥生成与保存:这个类在初始化时检查本地是否已有秘钥文件。如果没有,它会生成一个新的秘钥并保存到一个文件中。这个文件在后续的运行中用于加载秘钥。
-
生成一次性密码:
generate_otp
方法使用当前的秘钥来生成一个一次性密码。 -
验证一次性密码:
verify_otp
方法接受一个一次性密码作为输入,并验证它是否有效。
不用重复造轮子 ,真的是太爽了。
依赖包和算法
pyotp
是一个用于Python的库,它提供了生成和验证一次性密码(OTP)的功能。这些密码常用于双因素验证(2FA)过程中。pyotp
支持两种主要类型的一次性密码算法:基于时间的一次性密码(TOTP)和基于计数器的一次性密码(HOTP)。
TOTP和HOTP算法!
-
TOTP(Time-Based OTP):
- 基于时间的算法,通常每30秒生成一个新的密码。
- 广泛用于双因素验证,如Google Authenticator。
pyotp
中的TOTP实现遵循RFC 6238标准。
-
HOTP(HMAC-Based OTP):
- 基于计数器的算法,每次验证操作后计数器增加。
- 密码的生成依赖于初始计数器的值。
pyotp
中的HOTP实现遵循RFC 4226标准。
HOTP 的特点和适用场景
HOTP(HMAC-Based One-Time Password)是一种基于计数器的一次性密码算法,它的主要特点和适用场景如下:
特点
-
基于计数器:HOTP的核心是一个递增的计数器和一个秘密密钥。每次生成一次性密码时,计数器的值都会递增。
-
基于HMAC算法:HOTP使用HMAC(Hash-Based Message Authentication Code)算法结合秘密密钥和计数器值生成密码。
-
持久性:由于HOTP基于计数器,密码的生成不依赖于时间。这意味着即使在没有网络连接或同步的情况下,密码也能保持有效。
-
一次性:每个密码仅可使用一次,这增加了安全性。
-
标准化:HOTP遵循RFC 4226标准,确保了其跨平台的兼容性和一致性。
适用场景
-
物理安全设备:例如,用于银行令牌或安全ID卡,这些设备可以生成用于登录或进行交易的一次性密码。
-
无需时间同步的环境:在无法保证设备时间同步的环境中,如某些离线系统或具有不稳定时间源的设备,HOTP是一个更好的选择。
-
单次交易验证:用于验证单次交易或操作,如支付确认或系统访问,其中密码仅需使用一次且验证后即失效。
-
受限环境下的用户验证:在某些环境下,用户可能无法访问手机或其他基于时间同步的设备,HOTP可以提供一个可行的替代方案。
注意事项
- 同步问题:由于HOTP依赖计数器,服务端和客户端的计数器必须保持同步。如果计数器值不匹配,验证可能会失败。
- 安全存储:秘密密钥和计数器状态需要安全地存储和管理,以防止未授权的访问或篡改。
总的来说,HOTP由于其基于计数器的特性,非常适合在需要长期有效的密码或在无法保证时间同步的环境中使用。
TOTP的特点和适用场景
TOTP(Time-Based One-Time Password)是一种基于时间的一次性密码算法,它具有以下特点和适用场景:
特点
-
基于时间:TOTP密码的生成依赖于当前时间,这意味着密码在一个短暂的时间窗口(通常是30秒)内有效,之后将生成新的密码。
-
动态密码:由于密码随时间变化,这提供了很高的安全性,因为即使密码被拦截,它很快就会过期,无法再次使用。
-
基于HMAC算法:和HOTP一样,TOTP也使用HMAC(Hash-Based Message Authentication Code)算法结合秘密密钥和当前时间的表示(如时间步长的计数)来生成密码。
-
简易性和便捷性:用户不需要记住密码,只需通过手机或其他设备生成密码即可。
-
标准化:TOTP遵循RFC 6238标准,确保了其跨平台的兼容性和一致性。
适用场景
-
在线账户安全:TOTP是双因素验证(2FA)的流行选择,用于提高在线账户(如电子邮件、社交媒体、银行账户)的安全性。
-
网络服务登录:适用于需要额外安全层的网络服务,如VPN、企业门户网站和云服务。
-
需要频繁验证的场景:在需要用户频繁进行身份验证的场景中,如在线支付和敏感数据访问,TOTP提供了一种方便且安全的方式。
-
移动应用:由于移动设备普遍可用,TOTP在移动应用中很常见,用户可以通过安装类似Google Authenticator的应用来生成TOTP密码。
注意事项
- 时间同步:TOTP的安全性高度依赖于服务器和客户端之间准确的时间同步。如果时间偏差过大,可能导致密码验证失败。
- 用户体验:由于密码的频繁变化,某些用户可能会觉得不便。
- 安全存储:秘密密钥需要安全地存储和管理,以防止未授权的访问或篡改。
总的来说,TOTP由于其动态性和基于时间的特点,非常适合在线服务和应用中,特别是那些需要高安全性且用户可方便访问移动设备的场合。
几行代码就能轻松实现一套验证系统,真的是太爽了!
希望某些服务和APP直接采用这种发方式验证,既能保证安全,又能不受限于...