Отвечали уже не раз. Советую внимательно ознакомиться.
Также, на том же Хабре, есть более свежие вменяемы статьи:
Про хранение паролей в БД (обязательно читать комменты)
Правильные ответы по криптографии: 2018 год
Непосредственно по Вашим вопросам:
1. При
создании хэша пароля генерировать
случайную соль. Сохранять в БД хэш + соль. При
проверке пароля выбирать из БД хэш + соль, хэшировать полученный пароль с солью, и сопоставлять результат с хэшом из БД.
3. Для каждого хранимого хэша пароля своя уникальная соль.
4. Соль генерируется
достаточно случайной, потому что она
должна быть сложно угадываемой. Это означает, что энтропия для этого дела берется достаточно большая, и Вы можете не переживать за то, что чисто теоретически у Вас может сгенерироваться 2 одинаковые соли. Вероятность подобного случая примерно сравнимая с вероятностью того, что все молекулы воздуха в Вашей комнате возьмут и соберутся в одном углу, то есть,
крайне мала(с). И даже если Вы спустите весь запас удачи своей жизни на такой воистину уникальный случай, то ничего страшного и непоправимого при этом не случится - ну поймёт злоумышленник, что конкретно у этих 2х пользователей одинаковый пароль, ну и всё на этом, - пароли то всё ещё надо взламывать.
5. Да, можно. Хотя задача хэширования паролей и задача восстановления доступа по токену - это 2 разные задачи, с разными дано и целями, но первая задача является частью второй, ибо Вам нужно хранить в БД отпечаток секрета пользователя (коим временный токен восстановления и является). Алгоритм простой: генерируем случайный временный токен восстановления -> пишем в БД его отпечаток (хэш + соль) и время жизни -> отправляем токен пользователю -> пользователь переходит по ссылке с токеном -> проверяем валидность токена по его отпечатку и времени жизни -> заставляем пользователя ввести новый пароль. По сути, токен восстановления и являет собой одноразовый временный пароль, который предоставляет доступ для установки постоянного пароля.
Ну и традиционный совет: используйте для получения отпечатков секретов пользователей рекомендуемые алгоритмы (Argon2, Bcrypt, scrypt, и т.п.), а не собственные реализации. Там всё сделано под капотом как надо, ибо нюансов своих в этом деле тоже хватает (стоимость по времени, стоимость по памяти, constant time сравнения, и т.д.).