I have thought of a system for generating passwords which works as follows:

Take the following items:

1. A password, such as williamwallace.
2. A secret 1000 digit number which is stored on my computer.
3. The name of a website.

hex(sha512(site + password + number))


For example:

hex(sha512('google' + 'williamwallace' + '1456 … 3889'))


The generated hash can then be used as your password. How secure is this system?

• I don't think is secure: the hex output implies that you have a 16 elements alphabet. You should give a look to a pbkdf (password based key derivation function) as inspiration – ddddavidee Aug 3 '14 at 15:01
• The hex output is just a usable representation of the bytes output produced by the hash. Also, I am not concerned about the size of the alphabet, because the generated password will be quite long, which eliminates this issue. I am mainly interested in the security of the method. (If the method is secure, then the output can be tweaked to produce printable characters without using hex. However, if the method is not secure, there is no point fixing up the hex output.) – daviewales Aug 3 '14 at 15:34
• What are you trying to accomplish? Depending on your goal, it might be better to just generate random passwords and store them; just as you would store your 1000 digit random number. – QuadrExAtt Aug 4 '14 at 12:28
• I'm having difficulty finding a flaw in your logic @QuadrExAtt... It's a good point. – daviewales Aug 5 '14 at 13:08

There are some attacks on hashes keyed with a secret suffix. The proper primitive for deriving a secret from keys/passwords and an identifier is a key derivation function.

In your case, if the secret number is random a fast key derivation function, like HKDF, would be enough to expand the key into several site-specific hashes. In that case there's no need for the password, though, and 1000 digits is overkill for the random number – 256 bits is enough, or 512 to match the theoretical strength of SHA-512 based HKDF.

If the secret number is either not random or not secret, you should use a password based key derivation function, like PBKDF2 or scrypt. The former is standard, although you'll want to increase the iteration count from the default. The latter has some advantages, but hasn't been standardized or studied as much.

• The number should be secret, but I am working on the assumption that someone might find it. – daviewales Aug 5 '14 at 13:09
• Incidentally, I've changed my code to use Python's pbkdf2 function, rather than its sha512 function. I've also adjusted the iteration count so it takes just about half a second to generate a password. – daviewales Aug 5 '14 at 13:13
• @daviewales, that's a decent way to do it. As long as the number is secret there is no way to derive the site-specific hashes, and even if it is, PBKDF2 will slow down a brute force or dictionary attack on the password. Still, it will add only something like 20 bits to the effective security of the password, so you should use something much more secure than williamwallace – for example a six word Diceware passphrase. – otus Aug 5 '14 at 13:42
• I specifically chose 'williamwallace' because I knew that it was a bad password. (No point wasting good passwords by posting them on SE...) However, you make a good point. – daviewales Aug 6 '14 at 12:52

I don't see any obvious security problems in your approach. You can look into key derivation functions, that can provide some additional security in case one of the following occurs:

• A weakness is identified in the hash function

There is a few usability issues, that would have to be addressed as well:

• Different sites have different password policies (minimum password length, maximum password length, required characters, forbidden characters). There is no single function mapping from binary hash value to password string, which can be used with every password policy. Your current approach of using a hexadecimal string will run into two issues: Maximum length of password being 8 or 20 characters is not unusual. Requiring at least one non-alphanumerical character is also not unusual. Solution I propose for this is that you have different functions mapping from binary hash to password string, such you can choose one suitable for each site's particular policy. I think base64 is a better default than hexadecimal.
• You may sometimes need to change the password on individual sites more frequently than others. Along with the site name you could include information about when the password was generated. A granularity of one month seems like a good balance between these two factors:
• How often you may need to be able to change the password.
• How easy you can remember the correct time as well as the possibility to brute force this single field, in case you forgot when the password was created, but remember everything else.
• You may need to change your master password and keyfile because one of the two has leaked. But changing passwords for every site right away may not be feasible. To address this purpose, I would do the following:
• Create a new secret number and associated password
• Create a file containing the old password and secret number both encrypted using the new secret number and password.
• Before starting to use the new password check a couple of times a day for a couple of days, that you can remember the new password. Verify this by decrypting the encrypted data and compare the secret number.
• Once you have proven enough times that you can remember the new password, destroy the old clear text secret such that old passwords can only be accessed by decrypting using the new password.
• From this point use the new data for all new passwords and only use the decryption for passwords, that have not been updated yet.
• Record when the date on which the switch over was made.
• You've thought of everything! Your system for changing secret numbers is really good. I've known for some time that I would need to change my secret number in order to change my passwords, but I never developed a practical plan for that eventuality. Considering that the passwords will already be quite strong I imagine that most password creation rules could be satisfied simply by prepending 'A' and appending ';' to every password. – daviewales Aug 5 '14 at 13:37

I worked on a browser extension similar to what you are proposing for a tech company. There's also a project out of Stanford called PwdHash. Such schemes are nice, because they do increase the entropy of the generated password and make dictionary attacks more difficult.

The main problem I ran into were pragmatic ones. The solution works 99% of the time, then you run into a web site that only works in IE (and your extension only supports Chrome, Firefox,and Safari), or you run into a phone support line that requires your password, so you can't use the client side implementation.

As discussed above, it's also not perfectly secure, since it still subject to dictionary attacks unless the large secret is stored on the client, which is usually not desirable, because client side storage of the auth credential is unreliable in browsers and ties the user to a single computer. Also, a system that relies on client-side stored secrets might as well not use passwords at all.

There's a standard called Secure Remote Password, which attempts to take this a step further. It's based on knowledge proofs, rather than exchanging a cleartext hash. As such, it can't be dictionary attacked by an observer, unless the observer colludes with the authenticator.

In comparison, PBKDF2 is not particularly secure. It's effective just a slow hash, so constructing the dictionary takes longer.

• Secure Remote Password looks pretty cool, but I don't think it's relevant in this situation, because it requires the server to support it, which I can't really control. – daviewales Aug 5 '14 at 13:27
• Correct, if you don't control the protocol you can't use SRP. You can take a look at how PwdHash works, it's a relatively nice, entirely client-side browser extension that seems to align with your original question. – Jeff-Inventor ChromeOS Aug 6 '14 at 0:34

I don't see what you want to accomplish. Since there is randomness involved, it's not something that lets you deduce the passwords on another computer if you don't have the 1000 digit random number. Thus, you need to take the random number with you in a secure container (or transmit it in some other safe way). In that case, you might as well just store and transmit randomly generated passwords for every site that have nothing in common. The system you propose induces additional complexity compared to random passwords, and I don't see any gain from it.

• There are some practical advantages, like less storage (a 256-bit key can be used to derive any number of hashes), no need for encryption (to protect stored passwords), only online attacks against the password (unless a hash is known). However, a password manager is the tried and true option. – otus Aug 5 '14 at 15:09
• I disagree on that one doesnt need encryption to store the data needed for ops scheme. At least the random number must be protected. If you're able to protect that, you might as well protect passwords directly. Plus the storage gain is outweighted by the complexity that other people have brought forth (like changing of passwords). – QuadrExAtt Aug 5 '14 at 20:19
• The password is what protects the number. Encrypting with a different password would be equivalent to adding a second password to the hash. Anyway, I don't disagree that there are disadvantages. – otus Aug 6 '14 at 2:03