Если вы не используете SSL, то возникнут дыры в безопасности при выполнении шифрования на стороне клиента или хеширования в Javascript, так как человек из среднего атакующего может просто удалить код хеширования на стороне клиента перед передачей страницы пользователю.
Если вы используете SSL, то реализовать дополнительную защиту на стороне клиента будет мало. Единственный сценарий, в котором это может быть выгодно, - это когда злоумышленник может поставить под угрозу шифрование, но не целостность потока (поэтому он может только прослушивать данные). Это кажется маловероятным, но это возможно.
Для обеспечения дополнительной безопасности для предотвращения этого потребуется сначала хешировать пароль в соответствии с тем, как хешируется сервер (включая соль), а затем хешировать его с помощью предоставленного сервером случайно сгенерированного токена (который сервер также запоминает в сессия). Это гарантирует, что пароль не может быть получен кем-то, прослушивающим соединение (при условии, что целостность потока не нарушена), а также гарантирует, что хешированная версия не может быть использована при атаке воспроизведения (случайный токен сервера предотвращает его повторное использование). Если вы хэшируете пароль только на стороне клиента, ничто не мешает злоумышленнику просто использовать это хешированное значение для входа в систему. Помните, что это в дополнение к SSL, а не вместо него.
Независимо от способа передачи пароля, вы должны хранить только соленую хешированную версию пароля в вашей базе данных. В идеале следует использовать соль для каждого пользователя (которую вы также храните) и безопасную хеш-функцию (например, SHA-2 вместо SHA-1 или MD5).