Google身份验证器代码与服务器生成的代码不匹配 [英] Google Authenticator code does not match server generated code

查看:302
本文介绍了Google身份验证器代码与服务器生成的代码不匹配的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述


我目前正在使用两因素身份验证系统,在该系统中,用户可以使用智能手机进行身份验证.用户需要先对其进行验证,然后才能使用他们的设备.为此,他们需要扫描我给他们的QR码,然后输入随后显示的代码.


I'm currently working on a two-factor authentication system where user are able to authenticate using their smartphone. Before the user can make use of their device they need to verify it first. For this they need to scan a QR code I give them and enter the code that subsequently shows.


QR码的扫描工作正常,并且可以通过Google Authenticator应用正确读取.但是,生成的代码与我在服务器上生成的代码不匹配.


The scanning of the QR code works fine, and it gets read correctly by the Google Authenticator app. However, the generated codes don't match with the ones I'm generating on the server.


我尝试了几件事,希望能找到我的问题.


I have tried a couple of things in the hope of finding my problem.

  1. 我尝试直接插入两个默认密码: 'thiswasmysecretkeyused'和密码的base64.b32encode()编码版本: 'ORUGS43XMFZW26LTMVRXEZLUNNSXS5LTMVSA===='在Google Authenticator应用程序中,但是它们生成的代码均与服务器不同.

  1. I have tried directly inserting both a default secret: 'thiswasmysecretkeyused' and a base64.b32encode() encoded version of the secret: 'ORUGS43XMFZW26LTMVRXEZLUNNSXS5LTMVSA====' in the Google Authenticator app, but these both generated codes different from the server.

我读到密钥后面的====可能导致它不起作用,因此我尝试也添加不带这些字符的字符.仍然没有良好的结果(它们生成相同的代码)

I read that the trailing ==== from the key may cause it to not work, so I tried adding one without those as well. Still no good results (they generate the same codes)

我尝试使用另一种算法来生成TOTP代码,因为在不太可能发生的情况下,我正在使用该算法(答案.两种算法在使用相同的密钥时都会生成相同的代码.

I have tried using a different algorithm for generating TOTP codes, for in the unlikely event that the algorithm I'm using (django-otp) is incorrect. The different algorithm I used was taken from this answer. Both algorithms generated the same codes when using the same key.

我检查了系统时间.我看到操作系统正在显示15:03,就像我的智能手机一样.用time.time()datetime.datetime.now()在python中转储了时间之后,我看到返回的时间比操作系统时间晚了一个小时.显示14:03.我尝试在用于代码生成的时间戳中添加3600秒,但无济于事.

I checked what the time on my system was. I saw that the operating system was showing 15:03 just like my smartphone was. After dumping the time in python with both time.time() and datetime.datetime.now() I saw the returned time was one hour behind the operating system time; showing 14:03. I tried adding 3600 seconds in to the timestamp used for code generation, but to no avail.

我尝试了其他几件事,但还不太记得它们是什么.

I have tried several other things, but can't quite recall what they all were.

我在Google Authenticator中查找了接受密钥的代码,并验证了它是否需要base32字符串.据我所知,我对密钥的编码是正确的.从代码中(

I've looked up the code that accepts keys in Google Authenticator and have verified that it is expecting a base32 string. So my encoding of the key is correct, as far as I'm aware. From the code (EnterKeyActivity.java, line 78):

验证输入字段包含有效的base32字符串

Verify that the input field contains a valid base32 string

代码


生成密钥;

Code


Generating the secret key;

def generate_shared_key(self):
    # create hash etc.
    return base64.b32encode(hasher.hexdigest())

生成QR码;

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生成代码,请告诉我.

If you need any more code, such as django-otp actual totp generating code, let me know.


没有错误.


No errors.


我的直觉是,在密钥生成或将密钥传递给Google Authenticator的某个地方,我一定出了错.由于即使手动将密钥放入Google Authenticator也无法生成正确的代码.保存密钥后,Google Authenticator会对密钥进行更多操作吗?例如添加用户?


My hunch is that I must be going wrong somewhere with the key generation or with passing the key to Google Authenticator. Since even manually putting the key in Google Authenticator fails to generate the correct codes. Does Google Authenticator do something more with the key once it's been saved, such as adding an user?

我还注意到,在我使用的另一种算法中,其中的秘密首先被解码;

I also noticed in the other algorithm I used that the secret there gets decoded first with;

key = base64.b32decode(secret, True) 

我的原始密钥(SHA512哈希)是否错误?我应该还是不应该使用base64.b32encode()对其进行编码?如果我尝试扫描生成的QR码而不对哈希值进行编码,则Google Authenticator表示无法将其识别为(有效)密钥.

Is my original key (a SHA512 hash) wrong? Should I or should I not encode it with base64.b32encode()? If I try to scan the QR code generated without encoding the hash, Google Authenticator says it does not recognize it as a (valid) key.

推荐答案

好,在深入研究

Alright, after digging through the code of Google Authenticator I finally found what I was doing wrong.

很明显:Google身份验证器确实希望将base32编码的字符串作为秘密.因此,无论是手动输入还是通过QR码输入,将其提供给Google Authenticator时,都必须确保您的密码是base32编码的字符串.

Just so it's clear: Google Authenticator does expect a base32 encoded string as a secret. So whether you enter it manually or via a QR code, you have to make sure your secret is a base32 encoded string when you give it to Google Authenticator.

来自

存储

Google身份验证器会将您提供的密钥原样存储在数据库中.因此,这意味着它会将您的机密base32字符串直接存储在数据库中.

Storing

Google Authenticator is storing the key you give it in the database as is. So this means it stores the base32 string of your secret directly in the database.

来自来自

检索

当Google身份验证器从数据库中检索到机密时,它将对base32字符串进行解码,以便可以使用真正的机密.

Retrieval

When Google Authenticator retrieves the secret from the database, it decodes the base32 string so it can use the genuine secret.

来自来自

Mistake

我的错误是,在服务器端,我使用了base32编码的密钥来生成TOTP代码,因为我认为Google Authenticator也使用了该密钥.事后看来,这当然是很合逻辑的,但是我找不到太多有关此的信息.希望这会在将来帮助更多的人.

Mistake

My mistake was that, on the server-side, I was using the base32 encoded key for generating TOTP codes, since I thought Google Authenticator used that as well. In hindsight it's of course very logical, but I couldn't find too much info about this. Hopefully this will help out some more people in the future.

确保您传递给Google Authenticator的秘密/密钥是base32编码的字符串.确保在服务器端您没有使用base32编码的字符串,而是解码的字符串.在Python中,您可以按照以下步骤对您的秘密/密钥进行编码和解码:

Make sure the secret/key you pass to Google Authenticator is a base32 encoded string. Make sure that on the server side you're not using the base32 encoded string, but the decoded string. In Python you can encode and decode you secret/key as follows:

import base64

base64.b32encode(self.key)
base64.b32decode(self.key)

这篇关于Google身份验证器代码与服务器生成的代码不匹配的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆