Задний план
В настоящее время я работаю над системой двухфакторной аутентификации, в которой пользователь может аутентифицироваться с помощью своего смартфона. Прежде чем пользователь сможет использовать свое устройство, ему необходимо сначала его проверить. Для этого им нужно отсканировать QR-код, который я им даю, и ввести код, который отображается впоследствии.
Проблема
Сканирование QR-кода работает нормально, и приложение Google Authenticator правильно считывает его. Однако сгенерированные коды не совпадают с теми, которые я генерирую на сервере.
Что я пробовал
Я попробовал несколько вещей в надежде найти свою проблему.
Я попытался напрямую вставить как секрет по умолчанию:
'thiswasmysecretkeyused'
, так и закодированную вbase64.b32encode()
версию секрета:'ORUGS43XMFZW26LTMVRXEZLUNNSXS5LTMVSA===='
в приложение Google Authenticator, но оба эти кода генерировали коды, отличные от сервера.Я читал, что завершающий
====
ключа может привести к его неработоспособности, поэтому я попытался добавить еще один без них. По-прежнему нет хороших результатов (они генерируют те же коды)Я пробовал использовать другой алгоритм для генерации кодов TOTP, поскольку в том маловероятном случае, если используемый мной алгоритм (django-otp) неверен. Другой алгоритм, который я использовал, был взят из этого ответа. Оба алгоритма генерировали одинаковые коды при использовании одного и того же ключа.
Я проверил, сколько времени было в моей системе. Я увидел, что операционная система показывает
15:03
, как мой смартфон. После сброса времени в python сtime.time()
иdatetime.datetime.now()
я увидел, что возвращаемое время на один час отставало от времени операционной системы; показывает14:03
. Я попытался добавить3600
секунд к метке времени, используемой для генерации кода, но безрезультатно.Я пробовал несколько других вещей, но не могу вспомнить, что все они были.
- # P9 #
# P10 #
Код
Создание секретного ключа;
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)
Если вам нужен еще какой-либо код, например, фактический код генерации totp django-otp, дайте мне знать.
Ошибки
Ошибок нет.
Предчувствия
Мне кажется, что я где-то ошибаюсь с генерацией ключа или с передачей ключа в Google Authenticator. Поскольку даже вручную ввести ключ в Google Authenticator не удается сгенерировать правильные коды. Делает ли Google Authenticator что-то еще с ключом после его сохранения, например, добавляет пользователя?
Я также заметил, что в другом используемом мной алгоритме секрет сначала декодируется;
key = base64.b32decode(secret, True)
Мой исходный ключ (хэш SHA512) неправильный? Следует или не следует кодировать его с помощью base64.b32encode()
? Если я попытаюсь отсканировать QR-код, сгенерированный без кодирования хеша, Google Authenticator сообщит, что не распознает его как (действительный) ключ.
base64.base32encode()
верна, поэтому, возможно, опубликуйте и ту, которая также не совпадает. - person l'L'l   schedule 30.11.2015base64.b32encode()
в Google Authenticator? Что вы имеете в виду под несоответствующим? - person Bono   schedule 01.12.2015