How to choose secure passwords for insecure websites

Too many accounts

Most websites require an account to access even basic functionality and therefore need a dedicated password. A simple idea would be to reuse one single password for all these low-security websites but this is (i) insecure as it reduces the security of all your accounts to one single compromised account and (ii) many of these websites have different password requirements (e.g., different length, combination of upper and lower case, or even special characters). An other convenient alternative is to use a synchronized password manager that stores your passwords somewhere in the cloud. One still has to choose a new, secure password for each website but the cloud (e.g., Google Chrome or Mozilla's Firefox) will take care both of the synchronization across devices and backups. The disadvantage of password managers is that the password manager is now trusted and the cloud provider (often) has power over all passwords. If the password manager is compromised then all accounts are broken.

Customized passwords

A simple alternative I've used for some time now (for insecure websites) is concatenating the domain name of the website with a common shared password (e.g., "nebelwelt.netSharedKey"). This way, each website has its own dedicated password and the passwords are easy to remember. I've used this approach for all my 'insecure' websites that just forced me to register an account to access basic functionality and where I did not want to bother with a secure password.

Unfortunately, the security of all accounts depends on one plaintext password offender (one website that stores the password in plaintext) or one website with a weak hash algorithm that is reversible. In my case, I got burned by the big Adobe breach (I was forced to generate an Adobe account when I wanted to download an ebook from my local library because the ebooks are all protected with DRM crap - torrenting the books would have saved me from changing all passwords but that's another story). My shared password itself is pretty long and contains letters, numbers, and special characters so I assume that it will hold out for a bit but I still had to change all passwords for good measure.

Hashed passwords

To mitigate and protect from the single offender problem an attacker should not be able to guess the (obvious) shared password and domain part from just one single recovered cleartext password. Cryptographic hashes are a perfect one way function that accomplishes that task. The "echo -n nebelwelt.netSharedPassword | sha1sum | xxd -r -p | base64 | colrm $length+1" simple shell command generates the sha1 hash of the concatenated string, reencodes it from base16 to base64 to increase the amount of different character used, and cuts it down to the required length. Such a generated password will have very high entropy (in the base64 charset) and even shorter password should be more secure than any word combination you might choose yourself (combination of word lists is not as random as you might think) or 'random' letters you choose yourself as humans do a really bad job as random number generators. If the website requires a special character I just append an exclamation mark at the end (as my password already has high enough entropy I do not care about the couple of bits added through special characters).

If an attacker recovers one single account password all other passwords are still safe while it is still an easy scheme to remember. The only drawback is that instead of just concatenating the domain name and the shared key in the head I now have to run a quick shell command.

While this solution is not perfect I only have to remember one single password for all low-security websites and I only need access to a simple terminal to recover a password. Advantages are that neither do I need to trust a password manager nor can an attacker compromise multiple accounts from one single leaked password (oh, and as a pro tip: add an " " before the shell command so that your password does not end up in the bash history file).

[[ -n "$1" ]] || { echo -e "usage: give domain name to make hashed password. \n\n
./passhash 8\n
"; exit 0;}

[[ -n "$2" ]] || len=8
echo -n $1$key |sha1sum | xxd -r -p | base64 | colrm $(($len+1))