Secure Remote Password Protocol (SRP) - это протокол аутентификации паролей и обмена ключами, подходящий для аутентификации пользователей и обмена ключами в ненадежной сети. Еще в 1998 году браузер JavaScript был недостаточно эффективной платформой для обмена криптографическими ключами. В 2014 году, когда впервые появились Thinbus-SRP и Android KitKat 4.4, новые смартфоны оказались на высоте. Перенесемся в 2018 год, и более 90% телефонов Android работают под управлением Android как минимум 2014 года. Спустя двадцать лет после его изобретения для любого веб-сайта стало практичным использовать SRP в качестве доказательства пароля с нулевым разглашением для аутентификации пользователей. В этой статье будет рассказано, как это работает, и о некоторых преимуществах.
В статье Управление паролями и учетными данными в 2018 году Флориан Харвек описывает лучшие практики основных подходов к паролям:
- Хешируйте пароль с доменом веб-сайта в браузере.
- Хешируйте пароль со случайной солью на сервере.
- Симметрично зашифруйте результат для сохранения в базе данных.
SRP (RFC 5054) хранит верификатор пароля на сервере:
- Хешируйте пароль с именем пользователя и случайной солью в браузере. RFC использует SHA1 в качестве хэш-функции, но Thinbus-SRP использует SHA256.
- Также в браузере используется математика по модулю N для генерации верификатора соленого пароля.
- Хотя это не рекомендуется в RFC, также рекомендуется симметрично зашифровать получившийся верификатор, чтобы сохранить его в базе данных. Случайная соль также должна храниться в базе данных, поскольку она используется клиентом для аутентификации.
Window.crypto.getRandomValues - широко поддерживаемый способ генерации случайной соли. Thinbus-SRP использует полифил на случай, если браузер не поддерживает getRandomValues.
Для аутентификации пользователя с помощью верификатора SRP имеет характеристики протокола "запрос-ответ". Thinbus-SRP использует версию SRP RFC 5054 для этого обмена, которая подробно описана в разделе 2.6:
- Сервер загружает соль. Он генерирует частное случайное значение «b», которое хранится в кеше. Он передает клиенту соль и публичную ценность «B».
- Клиент хеширует имя пользователя, соль и пароль вместе. Он генерирует частное значение «а» и общественное значение «А». Он использует все данные для создания общего криптографического ключа. Затем он хеширует «A», «B» и общий ключ вместе. Он отправляет на сервер "A" и хэш.
- Сервер использует верификатор «A» и «b» для создания одного и того же общего криптографического ключа. Затем он хеширует «A», «B» и общий ключ и сравнивает его с тем, что отправил клиент. Если есть совпадение, пользователь аутентифицируется.
- Последний шаг, если пользователь был аутентифицирован, - это подтверждение сервером клиенту. Он добавляет «B» в хэш клиента и общий ключ. Он отправляется клиенту, который генерирует то же значение. Если есть совпадение, это подтверждает клиенту, что сервер сгенерировал тот же общий ключ, поэтому он должен знать верификатор, соответствующий паролю.
Этот протокол аутентификации имеет дополнительный обход сервера, но дает гораздо более надежные гарантии безопасности. RFC 5054 - это спецификация TLS, и протокол может быть выполнен в виде открытого текста. Никто, наблюдающий за солью, A, B или любым из хешей, не узнает ничего ни об общем ключе, ни о пароле. Обмен хешами, которые используют случайные одноразовые значения, является доказательством пароля с нулевым разглашением для сервера. Сервер узнает только то, что пользователь знает пароль, который использовался для генерации верификатора. Пароль всегда солится в браузере. Для восстановления пароля можно использовать только силовую атаку на верификатор, который является частным для сервера. Использование библиотеки надежности пароля и базы данных HiBP при создании верификаторов в браузере может сделать такие атаки методом грубой силы невозможными.
Хотя аутентификация SRP может выполняться с использованием обычного текста, всегда рекомендуется выполнять ее по HTTPS для дополнительной безопасности. Ключевым моментом является то, что традиционные подходы зависят от безопасности HTTPS. В тот момент, когда кто-либо входит на ваш сайт, полагаясь только на TLS или HTTPS, у вас хрупкая безопасность, когда злоумышленник находится в одном шаге от получения токена сеанса:
- Heartbleed показывает, что HTTPS - нетривиальный код, в котором могут быть ошибки безопасности.
- В современных общих облачных сервисах HTTPS завершается на балансировщике нагрузки, и трафик проходит через общие виртуальные машины в незашифрованном виде.
- Легко ввести ошибки и неправильные настройки, которые приводят к утечке токенов сеанса.
- Широкая публика не осведомлена о безопасности и может быть обманута с помощью атак типа «злоумышленник в середине» на «бесплатный» Wi-Fi, или использовать взломанные устройства, использующие троянские веб-прокси, или работать в крупных фирмах, которые устанавливают коммерческую программу «человек в сети». -средние прокси
Поскольку аутентификация SRP через HTTP сама по себе выполняет согласование общего ключа TLS, она неуязвима для всех этих опасностей. В качестве дополнительного преимущества вы можете использовать сгенерированный общий ключ для дополнительной безопасности. Например, вы можете использовать SRP для защиты спокойного API с использованием http-hmac-spec подписи запросов и ответов.
Вы можете получить библиотеку Thinbus-SRP с сайта npmjs.com. Есть совместимые бэкенды для node.js, PHP, python и Java. Любой язык, имеющий большую библиотеку десятичных математических вычислений, которая может выполнять криптоматематические операции, может реализовать серверную часть протокола. Так не пора ли вам получить серьезную эшелонированную защиту и использовать SRP для защиты своих сайтов и API?