9

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.

Create a password like this:

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?

Mike Edward Moras
  • 18,161
  • 12
  • 87
  • 240
daviewales
  • 193
  • 4

4 Answers4

10

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:

  • Your password leaks
  • Your secret number leaks
  • 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.
kasperd
  • 1,387
  • 1
  • 10
  • 23
6

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.

otus
  • 32,462
  • 5
  • 75
  • 167
5

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.

2

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.

QuadrExAtt
  • 328
  • 2
  • 11