chriszarate / supergenpass

A free bookmarklet password generator.
https://chriszarate.github.io/supergenpass/
GNU General Public License v2.0
415 stars 162 forks source link

SGP should use much higher iteration count #82

Open nealmcb opened 7 years ago

nealmcb commented 7 years ago

I'm alarmed to see this at https://github.com/chriszarate/supergenpass/wiki/FAQ

SuperGenPass uses a one-way hash algorithm (base-64 MD5) to generate passwords. Specifically, it concatenates the master password and the domain name of the Web site (masterpassword:domain.com), hashes the result at least ten times (and until it satisfies the generated password requirements), and cuts the result to the desired length.

It is well known that one of the most important attributes of a hash function for passwords is that it be slow. Yes - it must be slow so that brute-forcing the password is hard. See e.g. How to securely hash passwords?

So the fact that you use a very fast hashing primitive (MD5) and may only iterate 10 times makes our passphrases and secrets much more vulnerable. Best practice these days seems to be an iteration count of more than 10000. I don't know what the performance in a browser would be, but it should certainly be higher, and perhaps be configurable (which would provide yet another way to increase the difficulty).

Of course using MD5 is also bad because it has been badly broken and is deprecated. I guess you provide SHA512 as an alternative which is much better. You should recommend that to folks and explain how to use it, and explain that over time as cracking speeds increase, people will want yet more iterations.

chriszarate commented 7 years ago

SGP is a password generator, not a password hasher. I mostly agree with your points, but SGP exists to provide consistent, unique passwords with minimum configuration. If you believe that resistance to brute-force attacks is paramount to your password security, then you should fork SGP and host your own version. It's easy to do and I'd be happy to help you or anyone else who wants to take that route.

However, choosing a strong master password—combined with common sense precautions like not writing down passwords, using anti-virus software, etc.—is a much easier route to good password security.

By way of example, here's my generated password for example.com using the default SGP settings (MD5). My master password is a reasonable length, complex but still easy to type. Should I be worried about brute-force attacks?

vhV8T8sQ9k

nealmcb commented 7 years ago

Resistance to brute-force attacks is paramount to most anyone's password security these days.

The underlying math is the same for a password hasher and a password generator, and the attacking code is very similar. I think we have to assume that many sgp users will generate passwords for sites with horrible password hashing techniques, which don't protect their password files well, and which at some point have their databases stolen and subjected to offline attacks. You and I know that you need a good master password. But many users just can't be bothered or are scared of forgetting it, so they make it short.

Given all that, attackers will be smart to assume that some people are using sgp with common settings, and will try to crack the combination of the password hash from the attacking site, and sgp, since at this point, with 10 MD5s, it is hardly any more work than just looking for raw passwords. Furthermore, finding a success will give them a very valuable master password that is more likely to be used on really high-value sites.

So there are good reasons to increase the number of iterations, and no good reason I can think of not to.

Can you point us to the place in the code that we would want to change the iterations?

Finally, I appreciate your offer of an example to try to crack - that's the right spirit! There's a useful discussion of 10-character passwords at How long would it take to crack 10 character password? : theydidthemath which suggests that 10 might be OK these days, depending on circumstances. But of course over time it will just get cheaper to break them. So I'd also suggest considering switching to 12-characters as a default, again since it probably has few downsides.

chriszarate commented 7 years ago

SGP's underlying library, supergenpass-lib, accepts a hashRounds property on its options object. You could add something like the following inside the generatePassword function after the options object is defined:

options.hashRounds = 10000;

You've articulated the risk of having a weak master password very well, and I couldn't agree more that it puts users at risk. I'm working on implementing a persistent warning prompt when a user enters a simple master password.

Regarding your suggestion of changing the default password length: Switching from 10-character to 12-character generated passwords provides no security benefit—generated password length is a simple truncation from the full hash length.

Choosing a longer or more complex master password, however, has immense security benefits, and that's what I'd want users to focus on. An attacker with access to one of your generated passwords has no idea what the length or complexity of your master password is; there is theoretically no upper limit on the time it would take to crack it. Choose master passwords wisely.

nealmcb commented 7 years ago

Good info - thanks! Going to 12 characters does help prevent brute-forcing of the generated password, in the normal case where the attacker isn't trying to crack the underlying sgp master password. Think of it this way. If you truncated the generated password to one character, it would be trivial to crack - just try all one-character passwords. 10 characters is good for most purposes, but 12 might be better.

scottchiefbaker commented 7 years ago

I think using MD5 with increased iterations is the wrong approach here. If you're looking at fundamentally changing the underlying algorithm, we'd be much better suited to switch to bcrypt or scrypt, as they're designed for this exact use case.

nealmcb commented 7 years ago

@scottchiefbaker I agree that bcrypt would be significantly better. I also forgot that there has actually been a Password Hashing Competition, which ended last year and selected Argon2 as the winner. It is hard to optimize for GPUs, so cracking attempts are hindered. It is implemented in C, with a python binding. The design document explains it all.

Note however that you should be wary of shiny new algorithms, even ones that have been carefully vetted, as explained by Thomas here: Are there more modern password hashing methods than bcrypt and scrypt? - Information Security Stack Exchange

Note also that scrypt is vulnerable to cache-timing attacks due to secret-dependent memory access patterns.

It might be more of a hassle than you want at this time, but good to know about. Switching to SHA-512 by default would help, switching to bcrypt would help more, and just increasing the iteration count will almost surely help a lot.

jpeg729 commented 7 years ago

If someone hacks dropbox and extracts the hash of my SGP password I must assume the worst, that he can brute-force it with ease. But then he will find an alphanumeric seemingly random password and will probably assume in order that either 1. I use the same password elsewhere, 2. I use a password manager, 3. I am smart, 4. I use SGP or one of its alternatives.

Quite frankly, 4 is pretty far down the list. I'm on the lookout for advice on passwords and people always say not to reuse them, they often give some advice on choosing a good password or using a password manager, but noone mentions mental hashing algorithms like Blum's mental hash, and noone ever proposes a simpler alternative to Blum's algorithm, and above all, noone ever, ever, ever mentions SGP.

What's more, we could even improve the situation considerably. If SGP implemented bcrypt, scrypt, pbkdf2, and one or two other highly secure algorithms, and proposed different versions with none of them being the default. Then even if an attacker knew I used SGP, and which version I used (which is a stretch), he would still have a hard time cracking the master password.

You are going to say that users need to remember which version they chose. True, but that can be made much easier by wrapping each version in a persona. bcrypt would be a bouncer named Bob, with a muscly photo and a penchant for ..., etc...

Of course, I could avoid using a master password and use a simple but non-obvious mental hash of the domain name instead, (how about 6 random letters that I use everywhere, followed by the vowels from the domain name in reverse order). Easy. And noone would ever guess any of my passwords and attackers would need a key-logger.

codewisdom commented 6 years ago

I agree with Chris on this. I've ran my SGP generated passwords many times against hash crack attacks. Guess what? They always fail. To my knowledge, no one is specifically targeting SGP generated passwords. Even with MD5. That being said, the risk is there. The issues highlighted with MD5 and performance are a concern. A few years ago, I forked SGP and created some improvements - primarily the use of a key file. Sadly, I got busy and put that side project on the backburner. Would anyone be willing to work on those improvements with me, including Chris?

nealmcb commented 6 years ago

Thanks folks. I'm sorry I've added to some confusion by bringing up the default 10-character length for generated passwords, which leads to discussion of cracking a web site database conventionally. That is quite distinct from my original point.

If I were an adversary, and had a hint that a given user used sgp (e.g. because they posted about it once online ;) ), I would do an indirect attack. Most people have lots of logins on sites with horrid password management, since those are so common. If I happened to have a dump of a hashed password database (and I know lots of such databases can be found online, and many more via the dark web), then my attack wouldn't a normal one directly against the hashed passwords.

Instead, as I noted earlier, I would guess lots of master passwords, add in the domain name from a hacked database, and then hash that again to compare against their hash from the database.

So now for each master password guess, I just have to do 10 MD5 hashes, then perhaps 2 SHA-1 hashes, if the site uses SHA 1, for each guess. (Salting also won't be much of a defense in this case, since I have the DB with salts.) I can now try billions of master passwords per second using a GPU.

If the master password is weak, finding it wouldn't be hard.

I appreciate the info on how to update the hashRounds iteration count, and if I get a breather later in the year I might give it a shot. But just too busy right now....

For context, see the reception that Keeper Security got this week for a vulnerable way of generating random passwords, which I expect is harder to attack.

codewisdom commented 6 years ago

@nealmcb The level of effort you describe is significant and would require a state or organized criminally or politically motivated group aiming at a high-value target. How many HVTs are there that use SGP? Illegal hacking to make a point still happens, but less often because of the significant criminal risks that exist today. However, I agree with you wholeheartedly that the risk is there, I just think it is a lot smaller. @nealmcb, What do you think about a key file? My fork has working prototype of that code that supports drag and drop.

nealmcb commented 6 years ago

It seems to me that it all depends on the master password. Since "ordinary desktop computers can test over a hundred million passwords per second using password cracking tools running on a general purpose CPU and billions of passwords per second using GPU-based password cracking tools", a master password that is anything remotely like commonly used passwords will fall quickly to anyone who tries. And it is trivial as I understand it to at least require thousands or millions of times as much effort, just by doing lots of iterations in SGP.

Offhand a key file sounds like it would also be nice, but it helps only if users use it, and keep it secure, and don't lose it. So not really a substitute for just using a slow password generation approach. Thanks.

jpeg729 commented 6 years ago

I think that the greater danger comes from room-mates, co-workers, and disgruntled family members. It is much easier for them to know that one uses SGP and with a little effort they can probably obtain a few leaked passwords. Once that is done they can crack the master password with ease.

Either way there is really no excuse for not using a slow password generation approach. So easy to implement, and so much harder for anyone to crack.

codewisdom commented 6 years ago

Does anyone want to work on improving SGP with a higher iteration count, deprecating or removing MD5, defaulting to bcrypt, scrypt, or pbkdf2 or whatever gives us a good balance of performance and security, and perhaps add additional features like a key file? We'd probably have to fork the solution (and give it a new name) if @chriszarate is not interested in extending and improving the solution. We can keep talking or do something. :-).

jmichael2497 commented 5 years ago

i've been looking into these sorts of tools to try and find something to recommend to friends and family that don't want to use a password manager that would need to be synced across devices.

the issues of hash type, iterations, and password size came up while i was reading about 2FA hardware and software systems. this publication used an example of a leaked site SHA1 hashed database (which is not much better than an MD5 hashed database apparently) and found weakly mangled little passwords in under 30sec.

http://www.flypig.co.uk/?page=publications&ref=publication

David Llewellyn-Jones, Graham Rymer, "Cracking PwdHash: A Bruteforce Attack on Client-side Password Hashing", 11th International Conference on Passwords (Passwords 2016), Bochum, Germany, 7 December 2016. http://www.flypig.co.uk/papers/dlj-gr-passwords16.pdf

they suggest of course using a longer master password seed is very important... but also not relying on an easy and fast by design hash (like MD5) for obfuscation, instead something more cpu intensive involving PBKDF2 or Argon2, and more salt and iterations.

their https://github.com/llewelld/pwdhash-poc switched HMAC-MD5 to PBKDF2-SHA256 and the suggested features seems to be like what SGP is approaching from the library at least (but not exposed in mobile page) as i notice SGP uses SHA512.

i like the ability of SGP to filter and optionally toggle TLD only vs allow subdomain for extra salt automatically, which is oddly lacking in some other projects.

the https://github.com/tmthrgd/mpw-js is doing good things like using scrypt and PBKDF2-SHA256, and helps salting (labeled as context) with security questions to get site specific security answers, and has a little counter box, but leave a stray dot or slash in the url and get unexpected password since it isn't filtered.

i'm going to poke around the code and see if these are modular enough to maybe combine some features together, swap hash types, and remove length limits (i notice SGP has 24, MPW has 20, PWH-POC unlimited). although it is possible to just use multiple tools and copy paste from both plus a mental blob for the super extra security conscious that don't want final output to be strictly generated only by a tool.