If you’re taking passwords from users, here are some commandments you need to follow:
Don’t Impose a Maximum Length Limit
This is one of the most critical. One of the best things anyone can do to make their password — or pass phrase — more secure is to make it longer. Increasing the number of characters means an exponential increase in the time it will take to brute-force it (all other things being equal). If you impose, say, a 12-character maximum on someone who wanted to use 13 characters, you’ve just stopped your user from making their password at least 26 times harder to break.
You can’t possibly be doing this for security’s sake! The only other excuse I can imagine is to conserve space in your database. But since you’re hashing your stored passwords anyway (you damn well are; see below), they’ll all be the same size no matter what, so that doesn’t wash, either. This restriction makes no sense at all. Just drop it.
Apparently Microsoft is imposing a 16-character maximum limit on its online passwords — but I don’t recall anyone ever accusing them of being a paragon of security best practices. Their claim that “our research has shown uniqueness is more important than length” doesn’t change the fact that length is important, and limiting it reduces your users’ security (and therefore yours, too).
Don’t Tell Me I Can’t Use a Certain Character
Any character. The more characters I can use, the greater I can make the key-space an attacker would have to search to brute-force my password. In short, if you tell me I can only use, say, letters and numbers but no spaces or punctuation, then you’re forcing me to make my password less secure than I’d otherwise make it on my own!
In particular, if you’re a security company, or involved in financial services or something of the sort that’s supposed to understand security, then you’ve just let me know that you don’t understand security, and I should take my business elsewhere.
And don’t you ever, ever tell me I can’t use characters like '
and ;
and "
and -
, because that lets me know you’re committing not one but two of the most heinous sins of password storage: You must be storing it in plaintext, and you’re using it unescaped in SQL queries. You’re trying to ensure that I’m not Little Bobby Tables — but not just with my username, but with my password as well. The only reason to do this is because you plan to use my password in an un-parameterized database query. Doing any un-parameterized query at all is a serious no-no, but there is no reason in the world why you should ever — ever — do one that involves my plaintext password. You should never store the thing in plaintext, and you should never run any queries that involve it. (What are you doing, trying to enforce a “password uniqueness” restriction?)
People who really want secure passwords will come up with passwords that range all over the key-space. If you don’t let them do so, you’re making it clear that you don’t really get security.
Don’t Tell Me I Have To Use Certain Characters, Either
It’s very simple: Let me use “correct horse battery staple“. It has roughly 44 bits of entropy, compared to only 28 or so for some gibberish like “k3yB0ardV0m!t”. Let me use “your momma wears army boots”, without forcing me to stick capitals and numbers in there.
Let me use something I can remember, so I don’t stick it to a Post-It note on my monitor.
An extra bonus about pass phrases like these: They’re much, much easier to type on mobile keyboards, since they don’t require special shift-keys to type uppercase, numbers, or symbols. This will just get more important as more people shift to mobile devices.
Edited to Add: And people were making fun of this even before I posted this entry:
Don’t Ever, Ever Store Passwords in Plaintext!
This one should be completely obvious, but apparently not. Then again, if you’re doing that, there’s probably nothing I can say that will convince you to stop.
Finally, here’s one that you probably hadn’t even dreamed of doing — but just in case: Don’t ever hard-code any username and password combination into your system! that’s just asking for trouble — the kind of trouble that afflicted Telstra a few months ago.