【发布时间】:2016-03-04 06:20:00
【问题描述】:
背景
我目前正在开发一个双因素身份验证系统,用户可以使用他们的智能手机进行身份验证。在用户可以使用他们的设备之前,他们需要先验证它。为此,他们需要扫描我给他们的二维码并输入随后显示的代码。
问题
QR 码的扫描工作正常,并且可以被 Google Authenticator 应用程序正确读取。但是,生成的代码与我在服务器上生成的代码不匹配。
我尝试了什么
我已经尝试了几件事,希望能找到我的问题。
我已尝试直接插入两个默认密码:
'thiswasmysecretkeyused'和base64.b32encode()加密版本的秘密:'ORUGS43XMFZW26LTMVRXEZLUNNSXS5LTMVSA===='在 Google Authenticator 应用程序中,但是这两个生成的代码都与服务器不同。我读到密钥后面的
====可能会导致它不起作用,所以我也尝试添加一个没有这些的。仍然没有好的结果(它们生成相同的代码)我尝试使用不同的算法生成 TOTP 代码,因为万一我使用的算法 (django-otp) 不正确。我使用的不同算法取自 this 答案。两种算法在使用相同密钥时生成相同的代码。
我检查了系统上的时间。我看到操作系统显示
15:03,就像我的智能手机一样。在使用time.time()和datetime.datetime.now()在python 中转储时间后,我看到返回的时间比操作系统时间晚一小时;显示14:03。我尝试在用于代码生成的时间戳中添加3600秒,但无济于事。我尝试了其他几种方法,但记不起它们都是什么。
-
我在 Google Authenticator 中查找了接受密钥的代码,并确认它需要一个 base32 字符串。因此,据我所知,我对密钥的编码是正确的。来自代码(EnterKeyActivity.java,第 78 行):
验证输入字段是否包含有效的 base32 字符串
代码
生成密钥;
def generate_shared_key(self):
# create hash etc.
return base64.b32encode(hasher.hexdigest())
生成二维码;
key = authenticator.generate_shared_key()
qrcode = pyqrcode.create('otpauth://totp/someurl.nl?secret=' + key)
生成 TOTP 代码;
def generate_code(self, drift_steps=0, creation_interval=30, digits=6, t0=0):
code = str(totp(self.generate_shared_key(), creation_interval, timestamp, digits, drift_steps))
return code.zfill(digits)
如果您需要更多代码,例如 django-otp 实际 totp 生成代码,请告诉我。
错误
没有错误。
预感
我的预感是我在生成密钥或将密钥传递给 Google Authenticator 时一定有问题。因为即使手动将密钥放入 Google Authenticator 也无法生成正确的代码。保存后,Google 身份验证器是否会对密钥执行更多操作,例如添加用户?
我还注意到在我使用的另一个算法中,那里的秘密首先被解码;
key = base64.b32decode(secret, True)
我的原始密钥(SHA512 哈希)是否错误?我应该还是不应该用base64.b32encode() 对其进行编码?如果我尝试扫描生成的 QR 码而不对哈希进行编码,Google Authenticator 会说它不会将其识别为(有效)密钥。
【问题讨论】:
-
base64.base32encode()字符串是正确的,所以也可以发布不匹配的字符串。 -
我假设您已经尝试按照these examples?中所示的方式实现?
-
@l'L'l 你能详细说明你的意思吗?我知道密钥是正确的(只要它们相同),但我应该向 Google Authenticator 发送一个
base64.b32encode()编码字符串吗? “不匹配的那个”是什么意思? -
@BobDylan 嗨,鲍勃,不,我没有尝试过这些,但没关系。我尝试的第二种方法只是生成 OTP,应该在服务器端和客户端生成相同的密码,但不会。
标签: python django two-factor-authentication google-authenticator one-time-password