Как работают одноразовые пароли на основе времени (ОТP)

Father

Professional
Messages
2,601
Reputation
4
Reaction score
633
Points
113
С ростом угроз кибербезопасности становится все более и более необходимым обновлять стандарты безопасности ваших веб-приложений. Вам необходимо убедиться, что учетные записи ваших пользователей в безопасности.
В настоящее время многие онлайн-приложения просят пользователей добавить дополнительный уровень безопасности для своей учетной записи. Они делают это путем включения двухфакторной аутентификации. Существуют различные методы реализации двухфакторной аутентификации, и аутентификация TOTP (алгоритм одноразового пароля на основе времени) является одним из них.
В этой статье объясняется, что это такое, как и зачем его использовать. Но прежде чем это понять, давайте сначала кратко рассмотрим, что означает двухфакторная аутентификация.

Что такое двухфакторная аутентификация?
Двухфакторная аутентификация (или многофакторная аутентификация) - это просто дополнительный уровень безопасности для учетной записи пользователя. Это означает, что после включения двухфакторной аутентификации пользователь должен пройти еще один шаг для успешного входа в систему. Например, обычные шаги для входа в учетную запись:

ZqTllcloHTWpzWYDh-YsnOggoitxJSicGiVj


Но после включения двухфакторной аутентификации шаги выглядят примерно так:
inJY5oemUFqSO2g5G6HvPpNt0I74XF0hlRKV

Таким образом, это добавляет еще один шаг к процессу входа в систему. Этот метод более безопасен, поскольку преступник не может получить доступ к учетной записи пользователя, если у него нет доступа как к обычному паролю пользователя, так и к одноразовому паролю.

В настоящее время существует два широко используемых метода получения одноразового пароля:
  1. На основе SMS: в этом методе каждый раз, когда пользователь входит в систему, он получает текстовое сообщение на свой зарегистрированный номер телефона, которое содержит одноразовый пароль.
  2. На основе TOTP: в этом методе при включении двухфакторной аутентификации пользователю предлагается отсканировать QR-изображение с помощью специального приложения для смартфона.
    Затем это приложение непрерывно генерирует одноразовый пароль для пользователя.
Метод на основе SMS не требует пояснений. Это легко, но у него есть свои проблемы, такие как ожидание SMS при каждой попытке входа в систему, проблемы с безопасностью и так далее. Метод на основе TOTP становится популярным из-за его преимуществ перед методом на основе SMS. Итак, давайте разберемся, как работает метод на основе TOTP.

Как работает метод на основе TOTP
Прежде чем это понять, давайте сначала обсудим, какие проблемы решит для нас этот метод.
Используя метод TOTP, мы создаем одноразовый пароль на стороне пользователя (а не на стороне сервера) через приложение для смартфона.
Это означает, что у пользователей всегда есть доступ к своему одноразовому паролю. Таким образом, он не позволяет серверу отправлять текстовое сообщение каждый раз, когда пользователь пытается войти в систему.
Кроме того, сгенерированный пароль изменяется через определенный промежуток времени, поэтому он ведет себя как одноразовый пароль.
Большой! Теперь давайте разберемся, как работает TOTP-метод, и попробуем реализовать описанное выше решение самостоятельно. Наше требование здесь - создать пароль на стороне пользователя, и этот пароль должен постоянно меняться.

Следующее может быть способом реализации этого решения:

Когда пользователь включает двухфакторную аутентификацию:
1. Внутренний сервер создает секретный ключ для этого конкретного пользователя.
2. Затем сервер передает этот секретный ключ телефонному приложению пользователя.
3. Телефонное приложение инициализирует счетчик
4. Телефонное приложение генерирует одноразовый пароль, используя этот секретный ключ и счетчик.
5. Приложение «Телефон» меняет счетчик через определенный интервал и восстанавливает одноразовый пароль, делая его динамическим.

Это должно сработать, но с этим связаны три основные проблемы:
  1. Как приложение будет генерировать одноразовый пароль, используя секретный ключ и счетчик?
  2. Как будет обновляться счетчик? Как веб-сервер будет отслеживать счетчик?
  3. Как сервер поделится секретным ключом с приложением телефона?
Решение первой проблемы определено в алгоритме HOTP.

Понимание HOTP:
HOTP означает «Одноразовый пароль на основе HMAC». Этот алгоритм был опубликован инженерной группой Интернета (IETF) как RFC4226. HOTP определяет алгоритм создания одноразового пароля из секретного ключа и счетчика.

Вы можете использовать этот алгоритм в два этапа:

1. Первый шаг - создать хэш HMAC из секретного ключа и счетчика.
Code:
// Obtain HMAC hash (using SHA-1 hashing algorithm) by secretKey and counter
hmacHash = HMAC-SHA-1(secretKey, counter);

2. В этом коде на выходе будет строка длиной 20 байт. Эта длинная строка не подходит в качестве одноразового пароля. Итак, нам нужен способ обрезать эту строку. HOTP определяет способ обрезать эту строку до желаемой длины.
Code:
// hmacHash[19] means 19th byte of the string.offset = hmacHash[19] & 0xf;
truncatedHash = (hmacHash[offset++] & 0x7f) << 24 | (hmacHash[offset++] & 0xff) << 16 | (hmacHash[offset++] & 0xff) << 8 | (hmacHashh[offset++] & 0xff);
finalOTP = (truncatedHash % (10 ^ numberOfDigitsRequiredInOTP));

Это может показаться страшным, но это не так. В этом алгоритме мы сначала получаем offsetпоследние 4 бита hmacHash[19]. После этого мы объединяем байты из hmacHash[offset]в hmacHash[offset+3]и сохраняем последний 31 бит в truncatedHash. Наконец, используя простую операцию по модулю, мы получаем одноразовый пароль разумной длины.
Это в значительной степени определяет алгоритм HOTP. Документ RFA4226 объясняет, почему это наиболее безопасный способ получить одноразовый пароль из этих двух значений.
Большой! Итак, мы нашли способ получить одноразовый пароль с помощью секретного ключа и счетчика. А как насчет второй проблемы? Как следить за счетчиком?
Решение второй проблемы находится в TOTP.

Понимание TOTP:
TOTP означает «Одноразовый пароль на основе времени». Это был опубликован RFC6238 по IETF.
TOTP использует алгоритм HOTP для получения одноразового пароля. Единственное отличие состоит в том, что вместо «счетчика» используется «время», и это дает решение нашей второй проблемы.
Это означает, что вместо того, чтобы инициализировать счетчик и отслеживать его, мы можем использовать время в качестве счетчика в алгоритме HOTP для получения OTP. Поскольку и сервер, и телефон имеют доступ ко времени, ни один из них не должен отслеживать счетчик.
Кроме того, чтобы избежать проблемы с разными часовыми поясами сервера и телефона, мы можем использовать временную метку Unix, которая не зависит от часовых поясов.
Однако время Unix определяется в секундах, поэтому оно меняется каждую секунду. Это означает, что сгенерированный пароль будет меняться каждую секунду, что не очень хорошо.

Вместо этого нам нужно добавить значительный интервал перед изменением пароля. Например, приложение Google Authenticator меняет код каждые 30 секунд.
Code:
counter = currentUnixTime / 30

Итак, мы решили проблему счетчика. Теперь нам нужно решить нашу третью проблему: поделиться секретным ключом с приложением телефона. Здесь нам может помочь QR-код.

Использование QR-кода​

Хотя мы можем попросить пользователей вводить секретный ключ напрямую в приложение телефона, мы хотим сделать секретные ключи довольно длинными по соображениям безопасности. Просить пользователя ввести такую длинную строку было бы неудобно.
Поскольку большинство смартфонов оснащено камерой, мы можем использовать ее и попросить пользователя отсканировать QR-код, чтобы получить от него секретный ключ. Итак, все, что нам нужно сделать, это преобразовать секретный ключ в QR-код и показать его пользователю.
Мы решили все три проблемы! И теперь вы знаете, как работает TOTP. Посмотрим, как это реализовать в приложении.

Как реализовать TOTP
Есть несколько бесплатных телефонных приложений (например, Google Authenticator App, Authy и т. д.), Которые могут генерировать одноразовый пароль для пользователя. Поэтому в большинстве случаев создавать собственное телефонное приложение не нужно.
Следующие псевдокоды объясняют способ реализации двухфакторной аутентификации на основе TOTP в веб-приложении.

Когда пользователь запрашивает включение двухфакторной аутентификации
Code:
// Generate a secret key of length 20.secretKey = generateSecretKey(20);
// Save that secret key in database for this particular user.saveUserSecretKey(userId, secretKey);
// convert that secret key into qr image.qrCode = convertToQrCode(secretKey);
// send the qr image as responseresponse(qrCode);

Пользователя просят отсканировать этот QR-код. Когда приложение телефона сканирует QR-код, оно получает секретный ключ пользователя. Используя этот секретный ключ, текущее время Unix и алгоритм HOTP, приложение телефона сгенерирует и отобразит пароль.
Мы просим пользователя ввести сгенерированный код после сканирования QR-кода. Это необходимо, потому что мы хотим убедиться, что пользователь успешно отсканировал изображение, а приложение телефона успешно сгенерировало код.

Пользователь вводит код, отображаемый в приложении.
Code:
// Fetch secret key from database.secretKey = getSecretKeyOfUser(userId);
if (codeTypedByUser == getHOTP(secretKey, currentUnixTime / 30)) {   enableTwoFactorAuthentication(userId);}

Здесь мы используем алгоритм HOTP на стороне сервера, чтобы получить аутентификацию на основе OTP по секретному ключу и текущему времени Unix. Если этот OTP совпадает с тем, который введен пользователем, мы можем включить двухфакторную аутентификацию для этого пользователя.
Теперь после каждой операции входа в систему нам нужно проверять, включена ли для этого конкретного пользователя двухфакторная аутентификация. Если он включен, то мы запрашиваем одноразовый пароль, отображаемый в приложении телефона. И если этот набранный код верен, только тогда пользователь аутентифицируется.

Пользователь вводит код, отображаемый в приложении телефона, для входа в систему.
Code:
// Fetch secret key from database.secretKey = getSecretKeyOfUser(userId);
if (codeTypedByUser == getHOTP(secretKey, currentUnixTime)) {   signIn(userId);}

Что произойдет, если пользователь потеряет код?
Есть несколько способов помочь пользователю восстановить код. Обычно, когда они включают двухфакторную аутентификацию, мы можем показать им секретный ключ вместе с QR-кодом и попросить их сохранить этот код в безопасном месте.
Такие приложения, как Google Authenticator App, позволяют генерировать пароль, вводя секретный ключ напрямую. Если пользователь потеряет код, он может ввести этот надежно сохраненный секретный ключ в приложение телефона, чтобы снова сгенерировать одноразовый пароль.
Если у нас есть номер телефона пользователя, мы также можем использовать метод на основе SMS, чтобы отправить пользователю одноразовый пароль, чтобы помочь ему восстановить код.

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

Автор: Пракаш Шарма
 
Top