TOTP (Time-Based One-Time Password) или просто OTP — это алгоритм для генерации одноразовых паролей, который не требует сторонних сервисов. Он работает локально на основе общего секретного ключа и текущего времени. Например, GitHub с 2024 года использует двухфакторную авторизацию (ввод пароля + ввод какого-то кода) только через OTP (в России авторизация через SMS недоступна).
Конечно, можно поставить какое-нибудь мобильное приложение, но телефон имеет свойство теряться…
Для интересующихся алгоритм генерации кодов выглядит так:
import hmac
import hashlib
import time
import struct
def generate_totp(secret_key, interval=30, digits=6):
# Текущее время в секундах
current_time = int(time.time())
# Временной шаг
time_step = current_time // interval
# Преобразуем временной шаг в 8-байтовое число (big-endian)
time_step_bytes = struct.pack(">Q", time_step)
# Преобразуем секретный ключ из Base32 в байты
secret_key_bytes = base64.b32decode(secret_key)
# Вычисляем HMAC-SHA1
hmac_result = hmac.new(secret_key_bytes, time_step_bytes, hashlib.sha1).digest()
# Выбираем смещение
offset = hmac_result[-1] & 0x0F
# Извлекаем 4 байта
truncated = hmac_result[offset:offset+4]
# Преобразуем в число
code = struct.unpack(">I", truncated)[0]
# Обрезаем до 6 цифр
code = code % 10**digits
return f"{code:06d}"
# Пример использования
secret_key = "JBSWY3DPEHPK3PXP"
print(generate_totp(secret_key))
Эти коды живут обычно 30 секунд, хотя возможны вариации.
Нам потребуются pass-otp
— расширение для популярного менеджера паролей Pass; и опционально zbar
или zbar-tools
в Ubuntu — для расшифровки QR.
sudo pacman -S pass-otp zbar
Ручная установка pass-otp
описана на GitHub.
Если вы еще не пользовались Pass, то стоит все-таки начать… Про его установку и настройку из пары команд в терминале я не считаю важным писать. Главное его достоинство в том, что он все хранит локально в зашифрованном виде, а не на чьем-то сервере в открытом.
Для генерации кода авторизации, как видно из примера выше, нужен только секретный ключ. Опишем на примере GitHub, как пользоваться Pass OTP:
- На любой странице ткните в правом верхнем углу по вашей аватарке;
- Найдите шестеренку и нажмите;
- В левом меню есть пункт Password and authentication;
- Где
Two-factor methods
находитсяAuthenticator app
, а рядом кнопкаEdit
, тыкаем ее; - Да, все выше можно и не выполнять, и достаточно просто перейти по этой ссылке.
- Видите QR? — Качайте. Либо можно нажать
setup key
, тогда будет показан только секретный ключ, в то время какpass-otp
нужна именно ссылка.
Чтобы получить ссылку:
$ zbarimg -q ~/Downloads/download.svg
QR-Code:otpauth://totp/GitHub:s3rgeym?secret=XXXXXXXXXXXXXXXX&issuer=GitHub
В ссылке otpauth://totp/GitHub:s3rgeym?secret=XXXXXXXXXXXXXXXX&issuer=GitHub
важен только параметр secret
, все остальное: пользователь и issuer
по сути являются просто комментариями. Если вы выбрали setup key
, то можете что угодно там вписать (ссылка должна иметь вид otpauth://totp/<issuer>:<account>?secret=<secret-key>&issuer=<issuer>
, где totp
— метод авторизации, кроме него есть менее безопасный hotp
, который сейчас не применяется).
Теперь нужно сохранить эту ссылку в Pass:
$ pass otp add github.com/s3rgeym/otp
Enter otpauth:// URI for github.com/s3rgeym/otp:
Retype otpauth:// URI for github.com/s3rgeym/otp:
Проверим:
$ pass otp github.com/s3rgeym/otp
123456
На GitHub не забудьте в поле Verify the code from the app
вставить код и нажать Save
. Это нужно для сохранения нового секретного ключа (сброса старого). Старый ключ восстановить невозможно (если нет какого-то способа его подсмотреть в приложении).
Прочие ссылки: