Чем меньше ограничений вы можете установить для того, какие символы разрешены в пароле, тем лучше - это увеличивает пространство поиска для кого-то, пытающегося перебором. В идеале, нет никаких причин запрещать какой-либо символ ASCII (кроме управляющих символов и таких вещей, как backspace / newline) в пароле.
Что касается ограничений по длине, минимальные ограничения хороши (например, не раздражайте своих пользователей, например, установив минимальную длину 10), максимальные ограничения плохие. Если кто-то хочет иметь 50-символьный пароль, пусть он - хранение не должно быть проблемой, пока вы хэшируете, поскольку хэши имеют постоянную длину.
Всегда хранит пароли в необратимой хэш-форме - в идеале, криптографически защищенной. Нет причин хранить их в обратимой форме (если кто-то забывает свой пароль, просто установите для него новый пароль, не пытайтесь его «восстановить»). Не пишите свои собственные алгоритмы хеширования - скорее всего, вы не являетесь экспертом по криптографии, и существует множество хороших проверенных алгоритмов хеширования с реализациями (либо в коде, либо в форме библиотеки) для примерно любой основной язык.
Посолите ваши хеши солью каждого пользователя достаточной длины, чтобы предотвратить Радужный стол Трещины.
Главы 5 и 6 в Pro PHP Security посвящены хранению и шифрованию паролей:
Некоторые соответствующие статьи: