Шаг первый: не доверяйте людям в Интернете, я предложу слабый алгоритм, который поможет мне его сломать.
Шаг второй: не создавайте свой собственный алгоритм и не внедряйте чужие в производственную систему, пока не получите степень доктора наук в области компьютерной безопасности
Шифрования недостаточно для защиты от атак повторного воспроизведения, если злоумышленник получит зашифрованный пароль, он будет им так же полезен, как и незашифрованный пароль, если этого достаточно для аутентификации.
Я бы предложил:
- Пользователь вводит туда пароль
- Клиент запрашивает токен с сервера
- Сервер возвращает уникальный случайный токен и сохраняет его в сеансе пользователя (с ключом, сохраненным на сервере)
- Клиент шифрует пароль + токен с помощью вашего открытого ключа и передает его на сервер.
- Сервер расшифровывает это, используя ваш закрытый ключ, и проверяет токен, соответствующий этому сеансу, ранее не использовался и не старше 30 секунд.
- Сервер проверяет, совпадает ли хеш пароля с хешем пароля пользователя, хранящимся в хранилище данных.
Все передаваемые данные будут по-прежнему видны, поэтому пользователи не получат никакой конфиденциальности (как в случае https). Ваш алгоритм шифрования, реализация шифрования и открытый ключ будут открытыми. Это относится к большому количеству текущей криптологии, большое количество алгоритмов разработано так, чтобы злоумышленник знал об этом.
Это не защитит от кейлоггерных или шпионских атак, так как они будут нацелены до того, как пароль будет зашифрован.
Мне неизвестны реализации асимметричного шифрования, реализованные в javascript, но в этом подходе нет ничего принципиально небезопасного.