I had a password for a credit card account which could not be more than 8 characters and couldn't contain 'special' characters or punctuation. This was probably done to either make the password human readable (over-the-phone, horrible idea), or because of some legacy system on their end. At some point the organization got smart and made a minimum of 6 characters, of which two needed to be numbers (but kept the other restrictions). This effectively narrows down pool the possible passwords for an attacker to guess, the opposite of what you want to do.
Therefore 1000 is a good minimum max length but 3 million is way to long.
Originally:
36^8 + 36^7 + 36^6 + 36^5 + 36^4 + 36^3 + 36^2 + 36
2,901,713,047,668 possible passwords
~41.4 bits
After: (36^8 - 26^2 * (8*7)/2) + (36^7 - 26^2 * (7*6)/2) + (36^6 - 26^2 * (6*5)/2)
2,901,650,810,624 possible passwords
still ~41.4 bits
Only 62,237,044 possibilities eliminated. Length is the most important factor, so this was probably a good decision if most of their users were using <= 6 char passwords, or not using numbers at all. And frankly, the financial sector should be using HSMs anyway, making weak KDFs irrelevant.Teach good password hygiene. Use keepassx. Use decentralized third party authentication with providers that know what they are doing and use 2FA and such!
But password restrictions achieve very little. Let people use their 12345 if they really want, they won't learn by watching the stove but by touching it. Some people are like that and we should educate, not babysit.
There are many sites which contain none of my personal info but I have to setup an account just to view website content. If my account gets hijacked, it might be used for spamming. But still If I could make a throwaway account with a blank password I would because I don't care about that accounts security. So surely some restrictions need to be in place if you're going to require signups.
I sucks for people that generate individual passwords based on a common password and site-specific data.
In the old days, if you stored the unencrypted password, it had to have a maximum length because somebody decided to make the db column 16 chars....
Same goes for charset limitations (e.g. try storing unicode characters in a database set to US-ASCII charset...) - with a hash your input does not matter - it is just a sequence of bytes that are hashed.
Lastly, the source of disallowing certain characters is the laziness of the implementers that couldn't be bothered to implement proper input encoding in their frontend