что такое totp код
TOTP (Time-based one-time Password algorithm)
С ростом числа угроз кибербезопасности, для разработчиков становится все более и более необходимым обновлять стандарты безопасности веб-приложений и быть при этом уверенными в том, что аккаунты пользователей в безопасности. Для этого в настоящее время многие онлайн-приложения просят пользователей добавить дополнительный уровень безопасности для своей учетной записи. Они делают это за счет включения двухфакторной аутентификации. Существуют различные методы реализации двухфакторной аутентификации, и аутентификация TOTP (алгоритм одноразового пароля на основе времени) является одним из них.
Чтобы понять, что из себя представляет TOTP и как он используется, необходимо сначала кратко рассмотреть более базовые понятия. Первое из них – двухфакторная аутентификация. Двухфакторная аутентификация (или многофакторная аутентификация) — это метод идентификации пользователя в каком-либо сервисе (как правило, в Интернете) при помощи запроса аутентификационных данных двух разных типов, что обеспечивает двухслойную, а значит, более эффективную защиту аккаунта от несанкционированного проникновения. Это означает, что после включения двухфакторной аутентификации пользователь должен пройти еще один шаг для успешного входа в систему. Стандартные шаги для входа в учетную запись – это ввод логина и ввод пароля (рис.1).
Рисунок 1. Порядок входа в учетную запись без двухфакторной аутентификации
Включение двухфакторной аутентификации добавляет в порядок входа дополнительный шаг (рис.2). Этот метод более безопасен, поскольку преступник не может получить доступ к учетной записи пользователя, если у него нет доступа как к обычному паролю пользователя, так и к одноразовому паролю.
Рисунок 2. Вход в учетную запись с подключенной двухфакторной аутентификацией
В настоящее время существует два широко используемых метода получения одноразового пароля:
На основе SMS. Каждый раз, когда пользователь входит в систему, он получает на указанный в учетной записи номер мобильного телефона текстовое сообщение, которое содержит одноразовый пароль.
На основе TOTP. При включении двухфакторной аутентификации пользователю предлагается отсканировать QR-код с помощью специального приложения для смартфона, которое в дальнейшем постоянно генерирует одноразовый пароль для пользователя.
Метод на основе SMS не требует пояснений. Несмотря на свою простоту, он имеет ряд проблем. Например, ожидание SMS при каждой попытке входа в систему, проблемы с безопасностью и т. д. Вследствие чего NIST еще в 2016 году рекомендовала не использовать его в новых системах аутентификации. В связи с минусами метода на основе SMS, метод на основе TOTP становится популярным из-за его преимуществ.
Также, стоит отметить, что в настоящий момент есть некоторые разногласия о том, что именно считать шагами, а что факторами аутентификации. Общепризнанным является существование трех факторов:
Знание, например, пароль
Обладание (в физическом смысле), например, смартфон
То, чем вы являетесь, например, биометрические данные
При этом шаги аутентификации являются субъединицами факторов, так, если для входа в систему необходимо введение двух паролей, то по сути мы используем только фактор знания. Если говорить о рассматриваемых нами методах, то метод на основе SMS принято относить к двухшаговой, но однофакторной аутентификации, т. к. пароль для SMS генерируется на сервере, а TOTP к двухфакторной, поскольку для генерации пароля необходимо наличие определенного приложения на смартфоне, что усложняет задачу доступа злоумышленников к этой информации.
Итак, используя для двухфакторной аутентификации метод на основе TOTP, мы создаем одноразовый пароль на стороне пользователя (а не на стороне сервера) через приложение для смартфона. Это означает, что у пользователя всегда есть доступ к своему одноразовому паролю. А также предотвращает отправку текстового сообщения сервером при каждой попытке войти в систему. Кроме того, сгенерированный пароль изменяется через определенный промежуток времени, что делает его, по сути, одноразовым.
Для реализации двухфакторной аутентификации с использованием TOTP необходимо учитывать основное требование – пароль должен создаваться на стороне пользователя, а также постоянно меняться.
Решение данной задачи может выглядеть следующим образом:
Когда пользователь включает двухфакторную аутентификацию, происходит следующее
Внутренний сервер создает секретный ключ для этого конкретного пользователя
Затем сервер передает этот секретный ключ телефонному приложению пользователя
Телефонное приложение инициализирует счетчик
Телефонное приложение генерирует одноразовый пароль, используя этот секретный ключ и счетчик
Телефонное приложение изменяет счетчик через определенный интервал и восстанавливает одноразовый пароль, делая его динамическим
Этот алгоритм включает в себя два этапа:
Создать хеш HMAC (используя алгоритм хеширования SHA-1) из секретного ключа и счетчика
В этом коде на выходе будет строка длиной 20 байт. Эта длинная строка не подходит в качестве одноразового пароля. Итак, нам нужен способ обрезать эту строку. HOTP определяет способ обрезать эту строку до желаемой длины
Это в значительной степени определяет алгоритм HOTP. Документ RFA4226 объясняет, почему это наиболее безопасный способ получить одноразовый пароль из этих двух значений.
Итак, мы нашли способ получить одноразовый пароль с помощью секретного ключа и счетчика. А как следить за счетчиком? Ответ на этот вопрос находится в TOTP. TOTP переводится как «Одноразовый пароль на основе времени». Он был опубликован IETF как RFC6238. TOTP использует алгоритм HOTP для получения одноразового пароля. Единственная разница в том, что здесь вместо «счетчика» используется «время», и это дает решение нашей проблемы. Это означает, что вместо инициализации счетчика и его отслеживания мы можем использовать время в качестве счетчика в алгоритме HOTP для получения OTP. Поскольку и сервер, и телефон имеют доступ ко времени, ни один из них не должен отслеживать счетчик. Кроме того, чтобы избежать проблемы с разными часовыми поясами сервера и телефона, мы можем использовать временную метку Unix, которая не зависит от часовых поясов. Однако время Unix определяется в секундах, поэтому оно меняется каждую секунду. Это означает, что сгенерированный пароль будет меняться каждую секунду, что не очень хорошо. Вместо этого нам нужно добавить значительный интервал перед изменением пароля. Например, приложение Google Authenticator меняет код каждые 30 секунд.
Итак, мы решили проблему счетчика. Теперь нам нужно решить нашу третью проблему: поделиться секретным ключом с приложением телефона. Здесь нам может помочь QR-код. Хотя есть возможность попросить пользователей вводить секретный ключ напрямую в приложение телефона, безопасность ключа зависит от его длины, и пользователю будет неудобно вводить такую длинную строку. Поскольку большинство смартфонов оснащено камерой, пользователь может использовать ее для того, чтобы отсканировать QR-код, и получить от него секретный ключ. Все, что для этого нужно – преобразовать секретный ключ в QR-код и показать его пользователю. В настоящее время есть несколько бесплатных телефонных приложений (например, Google Authenticator App, Authy и т.д.), которые могут генерировать одноразовый пароль для пользователя. Поэтому в большинстве случаев создавать собственное телефонное приложение не нужно. Следующие псевдокоды объясняют способ реализации двухфакторной аутентификации на основе TOTP в веб-приложении.
Пользователя просят отсканировать этот QR-код. Когда приложение телефона сканирует QR-код, оно получает секретный ключ пользователя. Используя этот секретный ключ, текущее время Unix и алгоритм HOTP, приложение телефона сгенерирует и отобразит пароль. Затем система просит пользователя ввести сгенерированный код после сканирования QR-кода. Это необходимо, чтобы убедиться, что пользователь успешно отсканировал изображение и приложение для телефона успешно сгенерировало код.
Здесь используется алгоритм HOTP на стороне сервера, чтобы получить аутентификацию на основе OTP по секретному ключу и текущему времени Unix. Если этот OTP совпадает с введенным пользователем, то появляется возможность включить двухфакторную аутентификацию для этого пользователя. Теперь, после каждой операции входа в систему, проверяется, включена ли для этого конкретного пользователя двухфакторная аутентификация. Если да, то запрашивается одноразовый пароль, отображаемый в приложении телефона. И если этот набранный код правильный, только тогда пользователь аутентифицируется.
Если пользователь потеряет код, есть несколько способов помочь пользователю восстановить его. Обычно, когда они включают двухфакторную аутентификацию, есть возможность показать секретный ключ вместе с QR-кодом и попросить их сохранить этот код в безопасном месте. Такие приложения, как Google Authenticator App, позволяют сгенерировать пароль путем прямого ввода секретного ключа. Если пользователь потеряет код, он может ввести этот надежно сохраненный секретный ключ в приложение телефона, чтобы снова сгенерировать одноразовый пароль. При наличии номера телефона пользователя возможно использовать метод на основе SMS, чтобы отправить пользователю одноразовый пароль, чтобы помочь ему восстановить код.
Двухфакторная аутентификация набирает популярность. Многие веб-приложения реализуют его для дополнительной безопасности. В отличие от метода на основе SMS, метод TOTP также не требует особых усилий. Так что эту функцию стоит реализовать для любого приложения.
Как работают одноразовые пароли
Вступление
Как показывает практика, существует определенное непонимание принципов работы одноразовых паролей (это те самые, которые используются в GMail, в спец. токенах платежных систем и так далее).
Прочитав эту небольшую статью, Вы разберетесь в принципе работы одноразовых паролей на основе хэшей, а заодно напишете на Python небольшую программу, которая умеет вычислять пароли для двухэтапной аутентификации Google.
Хэш-функция
Хэш-функция позволяет взять любые данные любой длины и построить по ним короткий «цифровой отпечаток пальца». Длина значения хэш-функции не зависит от длины исходного текста; например, в случае популярного алгоритма SHA-1 длина этого отпечатка составляет 160 бит.
Чтобы понять, почему значение всегда имеет одинаковую длину и не зависит от исходного текста, можно упрощенно представить хэш-функцию в виде кодового замка с колесиками. Вначале мы выставляем все колесики в «ноль», затем идем по тексту и для каждой буквы прокручиваем колесики в соответствии с некоторыми правилами. То число, которое окажется на замке в конце, и есть значение хэш-функции. Примерами таких функций являются MD5, SHA-1, ГОСТ_Р_34.11-94.
Не придумывайте свои хэш-функции, используйте стандартные реализации (например, в случае Python):
Идея хэш-функции в том, что она работает только в одном направлении: ее очень легко подсчитать для «Войны и мира», но практически невозможно по уже готовому значению хэш-функции найти документ, который даст такое же значение. Даже если изменить в документе всего одну букву, хэш изменится полностью:
В связи с этим возникает естественное желание использовать хэш-функцию для контроля целостности сообщений, которые Алиса посылает Бобу: Алиса подсчитывает для каждого своего сообщения значение SHA-1 и вкладывает его в конверт; Боб, самостоятельно подсчитав SHA-1 текста, может сравнить свой результат с Алисиным и удостовериться, что сообщение не было изменено где-то по дороге.
Однако мы забыли о Меллори, который находится где-то между Алисой и Бобом, перехватывает их переписку и вскрывает конверты! Он вполне может изменить сообщение, после чего подсчитать для него SHA-1 и приложить к письму; Боб сверит значения и ничего не заметит.
Проверка подлинности
Подумав, Алиса и Боб при встрече договариваются, что при подсчете SHA-1 они будут временно дописывать к тексту секретное слово, например, «Secret» (конечно, в реальности Алиса и Боб решили использовать куда более длинное слово, чтобы его было сложно подобрать). Меллори не знает это слово, а следовательно, даже если изменит сообщение, то не сможет скорректировать его хэш, не так ли?
К сожалению, тут есть проблемы. Да, Меллори не может изменить тело сообщения, но (раз он знает хэш от текущего текста) он всегда может дописать в конце «P.S. На самом деле все это чушь, нам пора расстаться, Боб» и просто досчитать хэш от остатка (вспомним аналогию с кодовым замком).
Чтобы защититься от этого, мы немного усложним нашу функцию:
Теперь дописывание чего-либо в конец сообщения полностью изменит исходные данные для «внешнего» вызова SHA-1 и Меллори остается вне игры.
Алиса и Боб только что придумали то, что называется HMAC (или hash-based message authentication code): основанный на хэш-функции код проверки подлинности сообщений. В реальности HMAC, принятый как стандарт RFC2104 выглядит чуть-чуть сложнее за счет выравнивания длины ключа, пары XOR’ов внутри, участия ключа во «внутреннем» хэше, но суть не меняется.
Не придумывайте свои реализации HMAC, используйте стандартные реализации, например, HMAC-SHA1:
Одноразовые пароли
Что такое «одноразовый пароль»? Это пароль, который бесполезно перехватывать с помощью кейлоггера, подглядывания через плечо или прослушивания телефонной линии — т.к. этот пароль используется ровно один раз.
Как можно было бы реализовать эту схему? Например, Алиса может сгененировать сотню случайных паролей и отдать копию Бобу. Когда Боб позвонит в следующий раз, он продиктует самый верхний пароль в списке, Алиса сверит его со своим, после чего оба вычеркнут его. При следующем звонке они используют очередной пароль и так далее, пока они не закончатся. Это не очень удобно: хранение списков, генерация новых паролей и так далее.
Лучше реализовать эту схему в виде алгоритма. Например, паролем является его номер по порядку, умноженный на секретное число. Пусть Алиса и Боб договорились, что секретным числом является 42; тогда первым паролем будет 42, вторым 84, третьим 126 и так далее. Меллори, не знающий алгоритма и секретного числа, никогда не догадается, какой пароль будет следующим!
Конечно, алгоритм лучше выбрать посложнее. Алиса вспоминает про HMAC и предлагает Бобу считать пароль номер N по формуле: HMAC(«Secret», номер-пароля). После этого им нужно договориться о ключе (в данном случае это «Secret»), зато потом Бобу нужно только помнить, какой по счету пароль он генерирует (например, двадцатый):
Впрочем, Бобу совсем не улыбается каждый раз диктовать такой длинный пароль. Они с Алисой договариваются, что будут использовать только его часть, например, последние 6 символов.
Некоторое время все идет хорошо. До момента, пока Бобу и Алисе не надоедает вести подсчет, какой по счету пароль они используют. Кто-то подсказывает им, что в качестве аргумента HMAC() вместо номера можно использовать все, к чему Алиса и Боб имеют одновременный доступ… например, текущее время!
Наши герои синхронизируют свои часы и договариваются, что будут в качестве аргумента HMAC() использовать unix time — количество секунд, прошедших с момента наступления эпохи UNIX (в UTC). Чтобы вводить пароль не торопясь, они решают разделить время на 30 секундные «окна»; таким образом, на протяжении 30 секунд действует один и тот же пароль. Естественно, Алиса, проверяющая пароли, в течение 30 секунд не позволяет использовать пароль повторно (просто запоминая его) и тем самым оставляет его по-настоящему «одноразовым».
Теперь пароль вычисляется по следующей формуле: HMAC(«Secret», unix_timestamp / 30).
Мы получили одноразовые пароли на основе текущего времени. Сгенерировать и проверить эти пароли может только тот, кто обладает ключом («Secret» в примере выше); иначе говоря, сервер и пользователь.
Следует отметить, что одноразовые пароли могут считаться и по другим алгоритмам; главное, чтобы алгоритм и секрет были известны обеим сторонам. Но т.к. у нас есть стандарт, дальше мы будем говорить именно о нем
OATH, TOTP, HOTP, RFC… WTF?
Итак, мы только что описали основные идеи, лежащие в основе:
1) HMAC, hash-based message authentication code: RFC2104
2) HOTP, hash-based one-time password: RFC4226
3) TOTP, time-based one-time password: RFC6238
Эти идеи — один из краеугольных камней инициативы Initiative For Open Authentication (OATH), направленной на стандартизацию методов аутентификации.
Двухэтапная аутентификация Google
Одноразовые пароли, основанные на времени (и подсчитываемые на основе алгоритма TOTP RFC 6238) используются также компанией Google в приложении Google Authenticator, которое можно установить на iOS, Android, BlackBerry. Это приложение автоматически генерирует одноразовые пароли раз в 30 секунд (в дополнение к основному паролю на Google Account). Это означает, что даже если Ваш основной пароль кто-то подглядит или перехватит, без очередного одноразового пароля в систему войти будет невозможно. Удобно.
ВНИМАНИЕ : Я НЕ НЕСУ НИКАКОЙ ОТВЕТСТВЕННОСТИ ЗА ВАШИ ДЕЙСТВИЯ С ВКЛЮЧЕНИЕМ И ВЫКЛЮЧЕНИЕМ ДВУХЭТАПНОЙ АУТЕНТИФИКАЦИИ GOOGLE; ВЫ СОГЛАСНЫ, ЧТО ВЫ ВЫПОЛНЯЕТЕ ИХ НА СВОЙ СТРАХ И РИСК.
На самом деле там нет ничего страшного (есть инструкции, есть trusted-компьютеры, есть резервные коды и т.д.), но если от души постараться, бездумно нажимая на кнопки, то вполне можно лишиться доступа к своему аккаунту. И все же: если не готовы экспериментировать, не трогайте Gmail; просто скачайте приложение Google Authenticator на телефон, вручную добавьте «ключ по времени» (например, «a abc def abc def abc» или просто отсканируйте QR-код ниже).
Для начала нам нужно получить секретный ключ, который используется для создания одноразового пароля. Его можно посмотреть на странице добавления Google Authenticator’а в настройках аккаунта, он находится под QR-кодом:
Обратите внимание, что если двухэтапная аутентификация уже включена, то старый ключ узнать нельзя: придется удалить старый и сгенерировать новый. Это несложно; главное, не забыть сразу обновить ключ и в Google Authenticator, если Вы им пользуетесь.
Ключ закодирован в Base32 (для удобства уберите пробелы и переведите буквы в верхний регистр).
Программа, которая подсчитывает текущий одноразовый пароль:
Теперь можно положить рядом запущенный Google Authenticator и сравнить значения.
upd #2: если хотите поиграть с 2-step verification от dropbox, в конце секрета допишите «======» (это необходимо для паддинга и корректной работы base32-декодера).
Почему вам больше никогда не стоит использовать Google Authenticator
Не бывает достаточной безопасности. С другой стороны, использование глючной или слабой защиты может дать вам шаткую иллюзию безопасности, в то время, как вы остаётесь уязвимым к разного рода угрозам.
Использование только паролей, в общем – плохая идея, мы выяснили это с тех пор, как появился Интернет. Мы осуществляем прогресс, двигаясь к миру без паролей, но в то же время, многие веб-сайты предлагают дополнительную защиту пользовательских аккаунтов с помощью Двух-Факторной Аутентификации (2FA).
В общем и целом, существует 2 типа такой аутентификации: Временный одноразовый пароль (TOTP) а также Универсальный Двух-Фактор (U2F). Вы можете быть уже знакомы с первым типом, поскольку он используется наиболее часто: во время логина, предлагается ввести одноразовый пароль, генерируемый вашим приложением на смартфоне, отдельным аппаратным устройством, или же присылаемый в СМС. Метод прост, но есть несколько простых способов, делающих его опасным.
Я видел предупреждения типа “мой телефон взломали” от трёх людей из Кремниевой Долины/Биткойн среды/венчурной тусни. Будьте на чеку, и включите 2FA.
Как работает TOTP?
Временный одноразовый пароль, в основном популяризованный приложением Google Authenticator, подтверждает вашу личность на основании общего секрета. Этот секрет дложен быть известен вам и вашему провайдеру.
Когда вы заходите на веб-cайт под своей учеткой, ваше устройство генерирует уникальный код, основываясь на общем секрете и текущем времени. Затем вам нужно вручную ввести этот код. Сервер генерирует точно такую-же штуку, основанную на том-же секрете, чтобы успешно сравнить и подтвердить запрос на авторизацию.
Обе стороны генерируют одинаковый хеш, из одинаковых исходных данных, делясь секретом в момент регистрации.
В чём неадекватность TOTP?
Метод весьма прост в использовании, однако, он не лишён нескольких уязвимостей и неудобств.
1. Вам необходимо вручную вводить код во время авторизации (логина)
2. Слишком громоздкий бэкап. Вам необходимо совершать много шагов, чтобы сделать бэкап секрета. Кроме того, хорошие сервисы обычно предоставляют резервные коды, вместо того, чтобы явным образом призывать сохранять секрет. Если вы потеряете ваш секрет, и логин вместе с резервным кодом, вам придётся выполнить весь процесс регистрации TOTP заново.
3. Коды бекапа высылаются через Интернет, что совершенно небезопасно.
4. У вас и провайдера один и тот же секрет. Если атакующий хакнет компанию и получит доступ и к базе паролей, и к базе секретов, он сможет проникать в любой аккаунт совершенно незаметно.
5. Секрет показывается простым текстом или QR-кодом. Он не может быть представлен в виде хеша. Это также означает, что скорее всего секрет хранится в виде текстового файла, на серверах провайдера.
6. Секрет может быть раскрыт во время регистрации, так как провайдеру необходимо выдать вам сгенерированный секрет. Используя TOTP, вам нужно верить в способность провайдеров защитить приватность секрета. Но можете ли вы верить?
Как работает FIDO/U2F?
Стандарт U2F, разработанный Альянсом FIDO, был создан технологическими корпорациями, вроде Google и Microsoft, под влиянием найденных уязвимостей в TOTP. U2F использует криптографию с публичными ключами для подтверждения вашей личности (Reddit – “Объясняйте, будто мне лет пять”). В противовес TOTP, в данном варианте вы являетесь единственным, кто знает секрет (приватный ключ).
Сервер отправляет вам запрос, который затем подписывается секретным (приватным) ключом. Результирующее сообщение отправляется назад на сервер, который может подтвердить личность благодаря наличию в его базе данных вашего публичного ключа.
Выгоды U2F:
1. Через Интернет никогда не пересылается секрет (приватный ключ)
Никакая конфиденциальная информация не будет опубликована, благодаря криптографии публичного ключа.
2. Легче использовать. Нет нужды применять одноразовые коды.
3. Приватность. С секретом не ассоциируется никакая персональная информация.
4. Бекап теоретически легче. Однако, не всегда возможен; например, вы не сможете бекапить Yubikey.
Так как, в случае использования U2F, нет разделяемого двумя сторонами секрета и нет конфиденциальных баз данных, хранимых провайдером, хакер не может просто украсть все базы и получить доступ. Вместо того, он должен охотиться на отдельных пользователей, а это намного более затратно по финансам и времени.
Более того, вы можете забекапить ваш секрет (приватный ключ). С одной стороны, это делает вас ответственным за вашу же безопасность, но с другой – вам больше не нужно доверять какой-то компании, чтобы защитить ваши секреты (приватные ключи).
TREZOR – U2F “по-нашенски”
TREZOR представляет собой маленькое отдельное аппаратное решение, разработанное для хранения приватных ключей и работы в качестве изолированного компьютерного окружения. Изначально разработанный, как безопасный “железный” кошелек для Биткойна, рамки его применения значительно расширились благодаря расширяемости асимметричной криптографии. Теперь, TREZOR может служить в качестве безопасного железного токена для U2F, вам также придётся дополнительно подтверждать логин нажатием кнопки на устройстве.
В отличии от некоторых других токенов, TREZOR всегда использует уникальную подпись для каждого зарегистрированного пользовательского аккаунта. Кроме прочего, устройство выводит U2F на совершенно новый уровень:
1. Легко бекапить и восстанавливать. TREZOR просит вас записать на листочке так называемое “зернышко” (recovery seed), в время первого запуска устройства. Это –, единственный одноразовый процесс из всех остальных на устройстве. Восстановительное зёрнышко представляет собой все секреты (приватные ключи), генерируемые устройством и могут быть использованы в любое время для “восстановления” вашего аппаратного (или “железного”) кошелька.
2. Неограниченное количество U2F личностей, все они сохраняются в рамках единого бэкапа.
3. Секрет безопасно хранится в TREZORе. Его никто никогда не узнает, так как он не может покинуть устройство. Их не смогут украсть ни вирусы, ни хакеры.
4. Защита от фишинга с подтверждением на экране. Кошелёк всегда отображает url веб-сайта, на котором вы логинитесь, а также то, что именно вы хотите авторизовать. Вы можете убедиться, что информация, отправленная в устройство, соответствует вашим ожиданиям.
5. Дополнительная информация по использовании U2F во время настройки, использования и восстановления TREZOR может быть найдена в нашем посте в блоге, или в Пользовательской Документации.
Безопасные характеристики асимметричной криптографии кореллируют с философией безопасности TREZOR. С поддержкой U2F в кошельке, мы вдохновляем пользователей использовать все доступные меры для защиты их аккаунтов и личных данных в онлайне.