Реализация Google Authenticator в Python
Я пытаюсь использовать одноразовые пароли, которые могут быть сгенерированы с помощью приложение Google Authenticator.
что делает Google Authenticator
в основном, Google Authenticator реализует два типа паролей:
- HOTP - одноразовый пароль на основе HMAC, что означает, что пароль изменяется с каждым вызовом, в соответствии с RFC4226 и
- истории английского футбола. - времени Одноразовый пароль, который меняется каждые 30 секунд (насколько я знаю).
Google Authenticator также доступен с открытым исходным кодом здесь:code.google.com/p/google-authenticator
код
Я искал существующие решения для генерации паролей HOTP и TOTP, но не нашел много. Код у меня есть следующий фрагмент кода, ответственный за создание HOTP:
import hmac, base64, struct, hashlib, time
def get_token(secret, digest_mode=hashlib.sha1, intervals_no=None):
if intervals_no == None:
intervals_no = int(time.time()) // 30
key = base64.b32decode(secret)
msg = struct.pack(">Q", intervals_no)
h = hmac.new(key, msg, digest_mode).digest()
o = ord(h[19]) & 15
h = (struct.unpack(">I", h[o:o+4])[0] & 0x7fffffff) % 1000000
return h
проблема, с которой я сталкиваюсь, это что пароль, который я генерирую с помощью вышеуказанного кода, не совпадает с генерируемым с помощью приложения Google Authenticator для Android. Хотя я пробовал несколько intervals_no
значения (ровно первые 10000, начиная с intervals_no = 0
), С secret
будучи равным ключу, предоставленному в приложении GA.
вопросы у меня есть
мои вопросы:
- что я делаю не так?
- как я могу генерировать HOTP и / или TOTP в Python?
- есть ли существующие библиотеки Python для этого?
подводя итог: пожалуйста, дайте мне какие-либо подсказки, которые помогут мне реализовать аутентификацию Google Authenticator в моем коде Python.
2 ответа:
я хотел баунти на мой вопрос, но мне удалось создать решение. Моя проблема, казалось, была связана с неправильным значением
secret
ключ (он должен быть правильный параметр для
Я хотел, чтобы скрипт python генерировал пароль TOTP. Итак, я написал скрипт на Python. Это моя реализация. У меня есть это info на Википедии и некоторые знания о HOTP и TOTP, чтобы написать этот скрипт.
import hmac, base64, struct, hashlib, time, array def Truncate(hmac_sha1): """ Truncate represents the function that converts an HMAC-SHA-1 value into an HOTP value as defined in Section 5.3. http://tools.ietf.org/html/rfc4226#section-5.3 """ offset = int(hmac_sha1[-1], 16) binary = int(hmac_sha1[(offset * 2):((offset * 2) + 8)], 16) & 0x7fffffff return str(binary) def _long_to_byte_array(long_num): """ helper function to convert a long number into a byte array """ byte_array = array.array('B') for i in reversed(range(0, 8)): byte_array.insert(0, long_num & 0xff) long_num >>= 8 return byte_array def HOTP(K, C, digits=6): """ HOTP accepts key K and counter C optional digits parameter can control the response length returns the OATH integer code with {digits} length """ C_bytes = _long_to_byte_array(C) hmac_sha1 = hmac.new(key=K, msg=C_bytes, digestmod=hashlib.sha1).hexdigest() return Truncate(hmac_sha1)[-digits:] def TOTP(K, digits=6, window=30): """ TOTP is a time-based variant of HOTP. It accepts only key K, since the counter is derived from the current time optional digits parameter can control the response length optional window parameter controls the time window in seconds returns the OATH integer code with {digits} length """ C = long(time.time() / window) return HOTP(K, C, digits=digits)