Thanks for looking. All sincerely helpful answers are voted up.
I use a password strength meter to let the user know how strong the password they've chosen is. But this password checker obviously doesn't cover how weak under a dictionary attack the password is. How can I check for that, and is it worth it?
Also my regular password checker runs initially with javascript in the browser (no transmission required). If I want to check for dictionary attack weakness, I'd have to transmit it to a script. My understanding is that I shouldn't transmit it in the clear.
Can someone help me sort this out. How do I check the password isn't weak under a dictionary attack and how do I encrypt it before transmitting to my script?
Extra info:
Why do I think I need the dictionary attack check in addition to the regular password meter? As some of you have pointed out, users can choose passwords like P#ssword or Yellow12. But most password strength checkers I've come across will treat this as a good password. At least I'm using Yet Another Password Meter and it does (and I actually think it's one of the better password checkers.) If anyone knows of a stronger password checker, please mention it, but only if you know for sure based on experience that it's stronger ;)
But my question really is: how do I conduct a dictionary attack check on the password? I read somewhere that it's done against the hash, but where do I do the search? Once I find out how to do it, I will then decide whether it's worth it or not.
thanks to everyone who's helped out so far :)
Opinions are going to vary and some people will say that checking for dictionary words is important. I disagree and instead favor requiring different cases of letters, numbers and special characters like !##$%^&*()_-=+. Obviously passwords should be case sensitive.
Dictionary attacks are much less likely to succeed with the presence of numbers and special characters. Lets say that there are 1000 common passwords. Now with the addition of a required upper case letter and special character lets assume the user is "lazy" and they choose to make the first letter capital and add a special character to the end. That 1000 sized dictionary is now over 30,000.
Additionally there should be account lockouts in place to avoid dictionary attacks. And possibly a throttle on how often an IP address can attempt to login depending on your application.
There may still be a case to avoid some very common passwords while running your script. I would for example not allow the word password p#ssword or any variation of password.
Edit: A captcha, while hated by most (including me) may be appropriate as well after a few failed logins to avoid brute force login attempts.
I'm coming to this question later than the others, and I'm surprised that no-one has pointed out that a dictionary check might not be exhaustive. At least no-one has said it in so many words.
I think you need a large dictionary, where each entry is hashed and compared to the hashed password. This will allow you to say the user's chosen password is not in your dictionary, but how will you be sure it's complete?
Obviously, you can't be sure. Do you include foreign words? Technical words?
Do password crackers have access to better dictionaries?
I think all you can do is advise users how to create a good password — show them a few examples — but let it be their choice.
And do the SSL thing.
One additional point - if you control the site, you can stop dictionary attacks by limiting the number of times a user can try a user/pass.
It is great you want your users to have better passwords and you should continue in that direction but a better solution for the dictionary/brute force attack would be an exponential backoff solution to failed login attempts. No real user will try and login 1000 times in 10 seconds with all different passwords.
If you are using proper complexity requirements (length, mix of casing, numbers, symbols, and perhaps forbid repeat a char consecutively) then I'd say it's not really worth it. If you're in a situation where that would be required then probably password authentication would not be good enough for your situation anyway.
SSL
If your website in any way or on any page requests sensitive personal information, including passwords, then you should enable and enforce SSL across the entire site. This will ensure that all passwords are transmitted in encrypted form from the browser to the server, and that nobody can sniff the passwords off the network or modify the pages in transit (and alter the form postback url's).
Password Meter
You should run your password meter entirely in the browser. You should accept any and all passwords (with a min length of, for example, 6 characters) that the user enters, but feel free to hint to the user, from within the browser, whether they have entered a weak or strong password.
Related
Note: This doesn't explicitly relate to programming, but I was hoping this can be explained from a programmers point of view.
There are two things I simply don't understand about current 'password strength ratings'. This all pertains to brute force entry. (If these 'password strength ratings' relate to any other type of breach aside from using a common/popular password please let me know).
1) Why does it matter if I include numbers/symbols/uppercase letters as long as the password system allows for the possibility of using them?
For example lets just say:
a) The systems accepted characters are a-z, A-Z, 0-9, and their "shifted values" '!' to ')', so 72 possible symbols.
b) I use a password of length ten, so 72^10 possibilities.
c) My password is not in the top 10,000 most common/popular passwords used. So 72^10 - 10,000 possibilties remain.
Wouldn't an all lowercase password like 'sndkehtlyo' be identical strength as 'kJd$56H3di' since they both share the same possibility of including the additional characters? Doesn't the brute force algorithm have to include those numbers/symbols/uppercase regardless of whether or not I use them? It seems like these rating systems believe a brute force attempt will try all 26^n lowercase passwords first, all 52^n passwords second, then all 62^n passwords, etc, etc.
2) Why does that even matter? I have yet to come across any password system that doesn't lock you out after some small fixed number of attempts (usually 5). How can brute force approaches even work these days?
I feel like I am missing something fundemental here.
1) Cracking a password doesn't need to happen in one pass. A well implemented brute force crack may iterate first through small ranges of characters and then work its way into caps and numbers. Starting with the simplest ranges first (maybe just lowercase a-z) will find passwords of those unfortunate enough to have constructed a weak password. They may also start with dictionary attacks or Most-common-passwords-used attacks first as they take very little time.
2) Crackers aren't going to brute force right through some online service's login prompt. Anyone truly intent on getting access to an account would retrieve the hash of a user's password and crack it on their own machine, not over the internet. While there are practically infinite ways to hash a password there are some very common methods that can be identified by properties such as the hash's character length. You can read more about common hash algorithms in this Wikipedia article.
1) All man-made passwords are not totally random. In other words, taking the human factor (e.g. memorability), the probability distribution of a password space is not even.
2) The attempt times restriction is used for authentication, which is a means of Access Control. It has nothing to do with the password strength. It is the system level control method and it is usually configurable. Of course, it is an effective weapon against brute force attacks, but one can still design a system without that access control method. Also, hackers may not crack into the system directly but they could intercept the user data from the network which contains encrypted password or anything else and use brute force or other ways to crack it. So a high-strength password scheme, a high-security crypto method and a well-designed access system could live together to make a strong security system.
In general, with a brute force system, you are correct. But, a lot of automated password crackers out there begin their searches by trying common english words and their combinations. For example: sports teams, states, dates, etc etc... So by having those special characters it immediately eliminates a lot of those possibilities. Generally, if you're worried about brute force, a much longer password is more secure than a shorter one with special characters.
In light of the recent Gawker Media password leak, I've realized that many users share the same passwords. To help encourage stronger passwords, would it be helpful if passwords are constrained to be unique among all users?
One immediate downside I could think of (besides account creation performance?) is being able to know that someone is using a given string as a password. This knowledge, combined with a list of users, could be quite dangerous.
Is there a way to mitigate that downside while retaining the alleged benefits of not allowing repeat passwords?
It's kind of like the XKCD kick bot where you aren't allowed to repeat short, unoriginal sentences like "yah" or "lol".
Edit^2: I thought you could unique-ify against a hash, but as someone pointed out, with varying salts, this would not have the intended effect. Good eye!
absolutely not.
It is critical that no information about passwords be available to users outside the system. If they can easy guess which passwords are in use, by discovering that a password is unavailable, then they can use those passwords on known usernames and get a good shot at gaining access.
An alternative is to find some kind of common passwords database, and prevent any user from using them.
eeeuh
I might be misreading your question, but I hope you do not store the actual password?
You should hash the password with a random salt. That way, there is no way for you to ever tell if one or more users have the same password.
If your systems, in any way, allows you to determine if two or more users have the same password, you are storing the passwords the wrong way.
I would suggest the follwing as you have already mentioned the disadvantage of using "unique# passwords for all
Educate the user's about strong password.
Ask user's to change password regularly.
Keep a "Password strength" meter while they type in the password.
Really don’t
As long as you have salts, the password won’t be stored the same way anyway.
If you want to ensure password security:
Pick a good hash (sha256, blowfish, etc.)
Use salts
Snap-in a password meter with a minimum threshold
A lot of those can be bundled with wordlists
Check out a post I made about it on reddit:
http://www.reddit.com/r/netsec/comments/ektb8/in_the_light_of_recent_gawker_breakout_lets_talk/
If password management is done correctly, the only person who should know their password is the user who created it in the first place. In my web sites, I never store the password in any form. I store a cryptographic hash (SHA-1 or some variant) of that password that is manipulated with some sort of unique "salt" padding. Essentially if two people did have unique passwords, there would be no way to tell.
Most of the passwords on that link you gave are all easily guessed dictionary passwords. Very weak, and easy to brute force. They would all be unallowed by any system with rudimentary password checking.
I'm working on an admin page in PHP in which a user system seems like overkill. I was thinking of just requiring one password to access the admin page, but I'm not sure if would be safe to do so. I can't see any specific security problems that this might pose, can anyone else think of any?
Edit: By "a user system is overkill" I meant that there is not likely to be more than one user.
Complexity of the passwords aside, there are two problems:
The passwords must be unique now
If you have user+pass, users can have the same password. Under your model, they all must have a unique one.
Limited tracability
A good reason for user accounts to see who does what. You remove this, a little, with a general password as you need to assume, again, a one-to-one matching between them, and users. This may or may not be an issue.
For some of my admin pages, I don't really have a "user" so much as I have two tokens that need to be entered (because I'm the only admin).
For general people signing up, though, and if the password is entered by them, this is not an appropriate plan. If it's just for your admin pages for you, and you generate passwords of an appropriate complexity, life will be good.
It suffers from the same issues as a shared login, making it impossible to revoke for a specific user (if someone leaves, a users computer is compromised, etc), along with the issue of being way more open to brute force attacks (as mentioned by others).
For something simple, that doesn't seem to need a full fledged user/pass system, why not use HTTP Auth built into the server? Easy to setup, doesn't need to be shared, but would require no extra code on the admin script.
To sum up what others have said: Fine as long as the password is not simple, but more vulnerable to brute-force attacks.
Solution: You can enforce a password-complexity policy, and you can throttle further login attempts - get it wrong once, next login is artificially slowed 4 seconds. Get it wrong again, 8 seconds, and so on.
Option: Use two fields - username and password - but make the user also just a static value, like the password. Twice the guessing, twice the effort, twice the security (and twice the hassle for users..)
You could actually throw in a CAPTCHA. That would thwart brute-force attacks pretty well.
There is no problems if your admins wouldn't use simple passwords, like 1234567.
I, have the opinion that having a single password makes the system MORE secure (not less), as long as both the password and system are secure.
The reason is that when you have several users, it just takes one of them with a bad password to be the "weak link in the chain"
That said, nothing wrong with it as long as essential security measures are in place - and keep in mind brute forcing is easier (so make sure it's impossible/ineffective)
I would think that for your admin page (one would think the most secure page) that you would want very tight security?
If your "admin" user has a "hard to discover" username and that is paired with a very secure password I would think that this would be a better system.
Ideally I think you would want to have a complex username and password:
e.g.
Username: e4t_Gjw3#gp
Password: q!-gr7cBFL045$bd
Update: based on the comments I thought I would elaborate on why user+pass is more secure than a pass of "e4t_Gjw3#gpq!-gr7cBFL045$bd".
Having both a username and a password doesn't double the security, it does much more than that.
Pretend that usernames and passwords are both 3 characters (from A-Z) no case-sensitivity.
To guess a password, using brute force, you would need up to: 26x26x26 = 17,576 tries.
To guess just a username, same conditions: 26x26x26 = 17,576 tries.
If you had to guess both but they didn't have to match it would be 17,576x2 = 35,152.
However, if you have to guess the username AND find the matching password it is more like:
17,576 usernames * 17,576 passwords = 308,915,776
Of course if you have up to 16 character usernames (using case-sensitivity, numbers, punctuation etc.) and the same for passwords, the number of possibilities is Insanely Huge and thus... secure.
Update2: I seem to have missed typing the key bit of info I was trying to relay in my update. In most systems I've seen or built, the username and password fields have a size restriction built into the SQL columns of 32, or 40, or X characters. In the ones I've seen where there is just a pass column, the size isn't typically doubled to 64, or 80 chars.
Obviously the pass-only column, and set value can be doubled in length to account for the lack of username - but I have rarely if at all seen this done.
As Jake said, there are many reasons not to do this but it depends on what your application is doing. You need to do enough to put amateur hackers off. Make sure the admin use a strong password - 10 digits, with at least one capital and one symbol or something like that.
Most security experts would still frown on this though.
Password only + Captcha is ideal, Captcha would automatically implement rate-limiting and a strong password will make it secure.
Passwords have lots of downsides but they remain the only technically straightforward way of giving some authentication to users.
Lets talk hypothetically about an education-type system. Lots of people with passwords, lots of people forgetting their password regularly, lots of CS students and others trying to brute others passwords actually, lots of internal phishing trips and such.
As the admin, not knowing the password will not 'keep you out' of the account anyway, so what's the downside of just assigning people random-junk passwords and not enforcing them to change them?
Just giving people strong passwords on slips of paper telling them to keep it safe or memorise and eat it..?
You will have two issues:
Moved your security problem
Your passwords being so strong, and impossible to remember, the security of your system will be pushed onto the fact that the password will be written on a note next to the screen, or saved somewhere obvious on the computers desktop
A more technical problem will be:
Security of the random number generator you use.
This is a legitimate problem if you are generating passwords automatically, and someone can query you for new passwords as often as they like (by creating new accounts). It is hard to solve as well, though you do have some options. Typically you want to get as many sources as possible (random.org, hotbits, cryptographically secure in your language), and combine them. But you shouldn't query the online services too much, and you probably won't get enough from them, so you'll need to rely solely on those retrieved from your cryptographically secure process. Which is 'generally' good, but I wouldn't feel too comfortable if I was continually handing this out, on a ask-and-ye-shall-receive basis.
Personally, I don't think this is such a bad idea, in your case (it's an idea I had about 5 years ago now; wow ...). But really think it over before doing it, and read the articles I've linked.
I'm a big fan of generating a sentence as a password if you can get away with it with your system. It's both easy to remember, and has many characters to guess. This attempts to mitigate the "sticky note problem" while staying fairly complex. :-)
The downside is that it is much more difficult to remeber and you won't always have the slip of paper with you.
Do as they do at my university: run a password cracker and if the password is too weak, require/request that it will be changed.
Although for Gods sake run the cracker on the passwords before they are encrypted.
I think that should work in organizations for which the security is not one of the main concerns. Otherwise a well-defined security policy should be used, which will require both to have strong passwords and change them regularly.
you said:
lots of CS students and others trying to brute others passwords actually,
lots of internal phishing trips and such.
If this happens, I guess there is something wrong with the infrastructure itself. To try brute force cracking, the attacker has to have access to the password file or do this live trying to get access to the system. The first case should not happen as the password files should not be accessible to anyone. The second one seems to be easy to counter - just limit the number of login attempts / slow down the rate of logins and of course do some auditing who tries such things.
Assigning predefined passwords does not seem to be a good idea - many people have their own ways of memorizing/creating passwords and if you force them to use something they don't like, they are more likely to write it down somewhere or just loose that piece of paper they've got.
I think the only advice is to develop an efficient scheme for dealing with forgotten passwords. If we assume some kind of educational institution, there may be other forms of authentication that can be used when the user requests to reset his/her forgotten password and the whole process can be made reasonably efficient.
Ok, so the whole problem with hashes is that users don't enter passwords over 15 characters long. Most only use 4-8 characters making them easy for attackers to crack with a rainbow table.
Solution, use a user salt to make hash input more complex and over 50chars so that they will never be able to generate a table (way to big for strings that size). plus, they will have to create a new table for each user. Problem: if they download the db they will get the user salt so you are back to square one if they care enough.
Solution, use a site "pepper" plus the user salt, then even if they get the DB they will still have to know the config file. Problem: if they can get into your DB chances are they might also get into your filesystem and discover your site pepper.
So, with all of this known - lets assume that an attacker makes it into your site and gets everything, EVERYTHING. So what do you do now?
At this point in the discussion, most people reply with "who cares at this point?". But that is just a cheap way of saying "I don't know what to do next so it can't be that important". Sadly, everywhere else I have asked this question that has been the reply. Which shows that most programmers miss a very important point.
Lets image that your site is like the other 95% of sites out there and the user data - or even full sever access - isn't worth squat. The attacker happens to be after one of your users "Bob" because he knows that "Bob" uses the same password on your site as he does on the banks site. He also happens to know Bob has his life savings in there. Now, if the attacker can just crack our sites hashes the rest will be a piece of cake.
So here is my question - How do you extend the length of the password without any traceable path? Or how do you make the hashing process to complex to duplicate in a timely manner? The only thing that I have come up with is that you can re-hash a hash several thousand times and increase the time it would take to create the final rainbowtable by a factor of 1,000. This is because the attacker must follow that same path when creating his tables.
Any other ideas?
Solution, use a user salt to make hash
input more complex and over 50chars so
that they will never be able to
generate a table (way to big for
strings that size). plus, they will
have to create a new table for each
user. Problem: if they download the db
they will get the user salt so you are
back to square one if they care
enough.
This reasoning is fallacious.
A rainbow table (which is a specific implementation of the general dictionary attack) trades space for time. However, generating a dictionary (rainbow or otherwise) takes a lot of time. It is only worthwhile when it can be used against multiple hashes. Salt prevents this. The salt does not need to be secret, it just needs to be unpredictable for a given password. This makes the chance of an attacker having a dictionary generated for that particular salt negligibly small.
"The only thing that I have come up with is that you can re-hash a hash several thousand times and increase the time it would take to create the final rainbowtable by a factor of 1,000."
Isn't that exactly what the Blowfish-based BCrypt hash is about? Increasing the time it takes to compute a hash so that brute force cracking (and rainbow table creation) becomes undoable?
"We present two algorithms with adaptable cost (...)"
More about adaptable cost hashing algorithms: http://www.usenix.org/events/usenix99/provos.html
How about taking the "pepper" idea and implementing it on a separate server dedicated to hashing passwords - and locked down except for this one simple and secure-as-possible service - possibly even with rate-limits to prevent abuse. Gives the attacker one more hurdle to overcome, either gaining access to this server or reverse engineering the pepper, custom RNG and cleartext extension algorithm.
Of course if they have access to EVERYTHING they could just evesdrop on user activity for a little while..
uhmm... Okay, my take on this:
You can't get the original password back from a hash. I I have your hash, I may find a password that fits that hash, but I can not log in to any other site that uses this password, assuming they all use salting. No no real issue here.
If someone gets your DB or even your site to get your config, you're screwed anyway.
For Admin or other Super Accounts, implement a second mean of verification, i.e. limit logins to certain IP ranges, use Client-Side-SSL Certificates etc.
For normal users, you won't have much chance. Everything you do with their password needs to be stored in some config or database, so if have your site, I have your magic snake oil as well.
Strong Password limitations don't always work. Some sites require passwords to have a numeric character - and as a result, most users add 1 to their usual password.
So I'm not entirely sure what you want to achieve here? Adding a Salt to the front of the users password and protecting Admin accounts with a second mean of authentication seems to be the best way, given the fact that users simply don't pick proper passwords and can't be forced to either.
I was hoping that someone might have a solution but sadly I am no better off then when I first posted the question. It seems that there is nothing that can be done but to find a time-costly algorithm or re-hash 1,000's of times to slow down the whole process of generating rainbow tables (or brute-forcing) a hash.