O código do Google Authenticator não corresponde ao código gerado pelo servidor

fundo

Atualmente, estou trabalhando em um sistema de autenticação de dois fatores em que o usuário pode se autenticar usando seu smartphone. Antes que o usuário possa usar seu dispositivo, é necessário verificar primeiro. Para isso, eles precisam digitalizar um código QR que eu forneço e digite o código que é mostrado posteriormente.

Problema

A digitalização do código QR funciona bem e é lida corretamente pelo aplicativo Google Authenticator. No entanto, os códigos gerados não correspondem aos que estou gerando no servidor.

O que eu tentei

Eu tentei algumas coisas na esperança de encontrar o meu problema.

Eu tentei inserir diretamente um segredo padrão:'thiswasmysecretkeyused' e umbase64.b32encode() versão codificada do segredo:'ORUGS43XMFZW26LTMVRXEZLUNNSXS5LTMVSA====' no aplicativo Google Authenticator, mas esses dois códigos gerados diferem do servidor.

Eu li que a trilha==== da chave pode fazer com que não funcione, então tentei adicionar uma sem as também. Ainda não há bons resultados (eles geram os mesmos códigos)

Eu tentei usar um algoritmo diferente para gerar códigos TOTP, pois no improvável evento em que o algoritmo que estou usando (django-otp) está incorreto. O algoritmo diferente que eu usei foi retirado deesta responda. Ambos os algoritmos geraram os mesmos códigos ao usar a mesma chave.

Eu verifiquei qual era o tempo no meu sistema. Eu vi que o sistema operacional estava mostrando15:03 assim como meu smartphone. Após despejar o tempo em python com ambostime.time() edatetime.datetime.now() Vi que o tempo retornado estava uma hora atrás do tempo do sistema operacional; mostrando14:03. Eu tentei adicionar3600 segundos para o registro de data e hora usado para geração de código, mas sem sucesso.

Eu tentei várias outras coisas, mas não consigo lembrar o que eram.

Procurei o código que aceita chaves no Google Authenticator e verifiquei que ele espera uma string base32. Portanto, minha codificação da chave está correta, pelo que sei. A partir do código (EnterKeyActivity.java, linha 78):

Verifique se o campo de entrada contém uma sequência base32 válida

Código

Gerando a chave secreta;

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

Gerando o código QR;

key = authenticator.generate_shared_key()
qrcode = pyqrcode.create('otpauth://totp/someurl.nl?secret=' + key)

Gerando o código 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)

Se você precisar de mais algum código, como o django-otp atual totp gerador de código, me avise.

Erros

Sem erros.

Hunches

Meu palpite é que devo estar errado em algum lugar com a geração de chaves ou com a passagem da chave para o Google Authenticator. Como a inserção manual da chave no Google Authenticator falha na geração dos códigos corretos. O Google Authenticator faz algo mais com a chave depois de salva, como adicionar um usuário?

Também notei no outro algoritmo que usei que o segredo é decodificado primeiro;

key = base64.b32decode(secret, True) 

Minha chave original (um hash SHA512) está errada? Devo ou não codificá-lo combase64.b32encode()? Se eu tentar digitalizar o código QR gerado sem codificar o hash, o Google Authenticator diz que não o reconhece como uma chave (válida).

questionAnswers(1)

yourAnswerToTheQuestion