Реализация 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.

вопросы

мои вопросы:

  1. что я делаю не так?
  2. как я могу генерировать HOTP и / или TOTP в Python?
  3. есть ли существующие библиотеки 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)