Это вопрос, вызванный исключительно любопытством, желанием узнать немного больше о криптографии и аутентификации. Заранее спасибо всем, кто найдет время ответить.
Вместо того, чтобы солить и хэшировать пароль, отправляя его на сервер для аутентификации, может ли что-то подобное работать? Клиент генерирует пару закрытый/открытый ключ из пароля и случайной соли. Открытый ключ и соль хранятся на сервере. Для каждого входа в систему сервер отправляет соль и случайно сгенерированное значение для подписи клиента. Клиент регенерирует закрытый ключ из пароля и соли, затем подписывает случайно сгенерированное значение и отправляет его на сервер. Сервер проверяет подпись соответствующим открытым ключом.
Чтобы замедлить атаку грубой силы, ключ должен быть получен из пароля и соли с использованием медленного KDF, прежде чем генерировать закрытый/открытый ключи.
В качестве альтернативы сервер может потребовать от клиента получить ключ из случайно сгенерированного значения, используя какой-нибудь медленный KDF, прежде чем оно будет подписано, хотя мне это кажется менее идеальным, чем простое замедление получения ключа. Чтобы сэкономить ресурсы сервера при проверке подписи, можно использовать механизм стиля Proof of Work вместо медленного KDF, где клиент должен найти одноразовый номер такой, что hash(randomly_generated_value + nonce) > some_set_difficulty, затем одноразовый номер подписывается и отправляется сервер для проверки. Сервер может даже изменять сложность, например увеличивать сложность для каждой неудачной попытки входа в систему.
Каковы были бы некоторые преимущества и недостатки такой схемы? Я подозреваю, что раскрытие соли при каждой попытке входа в систему будет проблемой.