Ok, this is probably a really stupid idea, but I can't really see why it would be a bad idea. Maybe someone can enlighten me.

Why couldn't you enter a password good hashing algorithm like bcrypt, and then use the hash itself as your password for the website?

Because of the Avalanche Effect, this could allow users to use subtle derivations of their regular password to create competently different (and possibly better) passwords to use on actual websites.

For example, let's say a users password is "password123", and they want to log into a few different sites, so they append the sites name to the beginning of their password like so:



And so on.....

Normally, this would be very bad practice, as it would be trivial for an attacker to guess this user's naming system for passwords. But if the user ran his passwords through a hashing algorithim BEFORE logging into these websites, and then using the hash itself as the password, we have something that is very easy to remember and (possibly) more secure.

Is there any disadvantage I'm not seeing to this?

  • Can we please have a link to the original question? – stiabhan Nov 16 '15 at 0:40

Nope. It's a great idea. The trick is getting those hashes into different sites' length and complexity requirements.

PwdHash is one great example. It uses HMAC-MD5, but it drops so many bits from the output it's probably fine. (That's a technical term. Besides, MD5 pre-image resistance is still unbroken.) More importantly, they solved the problem of length and complexity requirements nicely, and there's working software for it on many different platforms (Firefox, Chrome, Mac OS, iOS, Android, the website itself).

Master Password is another app, which uses HMAC-SHA-256, but is only available on Mac and iOS. Also, it is a bit wonky in its encoding technique. Its defaults are way too low-entropy because they try to be "pronouncable" by controlling vowel positions. I submitted a bug report and was told that entropy is irrelevant and to go soak my head. It's fine if you use the paranoid setting for serialization, but it's too much of a headache compared to PwdHash for me.

It's a bit sad that this is the state of the art in this category, and it's also sad that the PwdHash people didn't just use scrypt.

  • The use of HMAC is much better than simply catenating the password to the sitename Not that it matters - the approach is flawed because hashes are simply too fast/cheap to compute to be considered safe for this purpose. Being cheap to compute allows an adversary who has the site-specific password and a guess at the plaintext (the site name +/- some info) to launch a dictionary or brute-force attack against the master password. That's the reason for bcrypt and scrypt - they are deliberately expensive in terms of memory and CPU cycles in order to thwart dictionary and brute force-force attacks. – stiabhan Nov 16 '15 at 0:50
  • One bit of good news with these schemes is that they discard a lot of output bits. That means that the attacker will (probably) get a lot of false positives. – Reid Rankin Nov 16 '15 at 0:53

A construction like hash(site_name + pw) will generate a secure password as long as password is high entropy and the hash has sufficient bits (e.g., 128+ bits which your standard cryptographic hash will have; just don't use non-crypto hashes like crc32). If you use something like pw = password123 that is easily guessed then a sophisticated attacker may be able to figure out your scheme from seeing your password at a site they control and then brute force your password for all other sites (e.g., if your password for example.com is md5("examplepassword123") it may be possible to reverse it by testing passwords of the form md5(site_name + pw) -- you can generate billions of md5 hashes per second per computer. It is a bad idea relying on an attacker not knowing your password generation scheme -- instead you should rely on your actual passwords having high intrinsic randomness (see Kerckhoffs's principle).

However, if you use something like bcrypt, you'll be fine with a weak password since bcrypt creates a random 128-bit salt which provides more than enough entropy to prevent even the weakest password from being reasonable (assuming the salt used differs between your hashes). Please note you'll have to store this randomly created salt to be able to login again, so at this point it probably would have just been simpler to use a completely randomly generated password for each website you visit.

To give an example with bcrypt using python (in the ipython interpreter):

In [1]: import bcrypt

In [2]: bcrypt.hashpw('amazonpassword123', bcrypt.gensalt(10))
Out[2]: '$2b$10$//rLpdWc/0hljdOf90366u1uaRch7q59AxF0qcodHvDckO1nd..ky'

In [3]: bcrypt.hashpw('amazonpassword123', bcrypt.gensalt(10))
Out[3]: '$2b$10$eUsCtvQ9mvYA2qAEShaqjOqgYogRP4mohEag5bm3Hls10JPSQxU4y'

In [4]: bcrypt.hashpw('amazonpassword123', Out[2])
Out[4]: '$2b$10$//rLpdWc/0hljdOf90366u1uaRch7q59AxF0qcodHvDckO1nd..ky'

Note that hashing the same thing twice with bcrypt generates a completely different hash as they used two different randomly created salts (with 2^10 rounds of hashing); this is why Out[2] != Out[3]. This isn't problematic when checking passwords against a bcrypt hash (as the hash contains the salt), so you can just provide the hash stored in the database to use as the salt and then check that it matches the stored hash; this is why Out[2] == Out[4].

The other issue to worry about is sites silently truncating your password. Using say a full bcrypt hash, where the first seven characters are $2b$<lg(number of rounds)>$ may severely weaken your password. For example, a VPN provided by a well-known vendor I use for work truncates my user password to 8 characters (though allows me to type in much longer passwords -- it just only checks the first 8).

Not the answer you're looking for? Browse other questions tagged or ask your own question.