Код Google Authenticator не совпадает с кодом, созданным сервером

Фон

В настоящее время я работаю над двухфакторной системой аутентификации, где пользователи могут проходить аутентификацию с помощью своего смартфона. Прежде чем пользователь сможет использовать свое устройство, он должен сначала проверить его. Для этого им нужно отсканировать предоставленный им QR-код и ввести код, который впоследствии будет показан.

проблема

Сканирование QR-кода работает нормально и корректно читается приложением Google Authenticator. Однако сгенерированные коды не совпадают с теми, которые я генерирую на сервере.

Что я пробовал

Я попробовал несколько вещей в надежде найти свою проблему.

Я попытался напрямую вставить оба секрета по умолчанию:'thiswasmysecretkeyused' иbase64.b32encode() закодированная версия секрета:'ORUGS43XMFZW26LTMVRXEZLUNNSXS5LTMVSA====' в приложении Google Authenticator, но оба сгенерированных кода отличаются от сервера.

Я читал что трейлинг==== из-за ключа может не работать, поэтому я попытался добавить один без них. Все еще нет хороших результатов (они генерируют одинаковые коды)

Я попытался использовать другой алгоритм для генерации кодов TOTP, потому что в маловероятном случае, что алгоритм, который я использую (Джанго-OTP) это неверно. Другой алгоритм, который я использовал, был взят изэтот ответ. Оба алгоритма генерировали одинаковые коды при использовании одного и того же ключа.

Я проверил, сколько времени было в моей системе. Я видел, что операционная система показывает15:03 так же, как мой смартфон был. После сброса времени в Python с обоимиtime.time() а такжеdatetime.datetime.now() Я видел, что возвращаемое время было на один час меньше времени операционной системы; показ14:03, Я пытался добавить3600 секунд до метки времени, используемой для генерации кода, но безрезультатно.

Я пробовал несколько других вещей, но не могу вспомнить, что они все были.

Я посмотрел код, который принимает ключи в Google Authenticator, и убедился, что он ожидает строку base32. Так что моя кодировка ключа правильная, насколько я знаю. Из кода (EnterKeyActivity.javaстрока 78):

Убедитесь, что поле ввода содержит правильную строку base32

Код

Генерация секретного ключа;

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, дайте мне знать.

ошибки

Нет ошибок

Догадки

Я догадываюсь, что я где-то ошибаюсь при генерации ключа или при передаче ключа в Google Authenticator. Так как даже ввод ключа вручную в Google Authenticator не дает правильных кодов. Делает ли Google Authenticator что-то еще с ключом после его сохранения, например, добавляет пользователя?

В другом алгоритме, который я использовал, я также заметил, что секрет там сначала расшифровывается;

key = base64.b32decode(secret, True) 

Мой оригинальный ключ (хэш SHA512) неверен? Должен ли я или не должен кодировать это сbase64.b32encode()? Если я пытаюсь отсканировать QR-код, сгенерированный без кодирования хеша, Google Authenticator говорит, что не распознает его как (действительный) ключ.

Ответы на вопрос(1)

Ваш ответ на вопрос