1

I wanted to check if the following means of generating a hash for storage of a password was secure.

I have an username and password combo. In order to generate a secure hash, I am doing the following:

gen_password = SHA256(password + "my_site_name")

gen_salt = SHA256(username + password + "my_site_name")

hash = PBKDF2(gen_password, gen_salt, rounds)

Anyone see any weaknesses or problems with this approach? Generating and storing a salt is not an option, so I am hoping this method would work.

If anyone can offer improvements on this, that would be great!

Thanks.

user44821
  • 13
  • 2

1 Answers1

0

The weakness in your system is intrinsic: there is no real salt. From your comments, I suppose that you cannot (for some contextual reason) store a randomly generated salt. So what you do amounts to, basically, use the pair "user+site" as salt.

Your various hashes are complex and some parts are useless: there is no need to input the password in so many places. You should strive for simplicity; complexity is your enemy. Still, you have to contend with idiosyncrasies of PBKDF2 (if you want to use that function), so the following should be as safe as you can be:

s = SHA-256(username + '|' + sitename)
p = SHA-256(password)
hash = PBKDF2(p, s, rounds)

Note that I use a '|' character as separator, and I assume that such a character does not appear in the site name (this is to avoid spurious collisions). The extra SHA-256 on the password itself is only to avoid an issue of PBKDF2, which is that it becomes twice slower when the password length exceeds the length of the underlying hash function (64 bytes for SHA-1 and SHA-256). If you are sure that your passwords will never exceed 64 bytes, then you can remove the second hash and use 'password' directly in PBKDF2.

Main remaining issue: if the user changes his password, the new password and the old password will use the same pseudo-salt. If an attacker can get both hash values, then he can try to break both for the cost of breaking only one. A similar problem occurs if you destroy a user account and then reuse the same user name. You cannot avoid this problem as long as you don't store a salt-like value (randomly generated) along with the hash values.

Improvements: you may want to change some parameters. For instance, if your server is a PC (64-bit, or at least a PC with SSE2 and using OpenSSL for the hash function implementation), you may want to make sure that PBKDF2 relies on SHA-512 instead of SHA-256 or SHA-1: SHA-512 will be efficient on your PC but make life harder for an attacker with a GPU (usual GPU are less comfortable with 64-bit integer types). You may also want to consider switching from PBKDF2 to Bcrypt, for the reasons exposed there.

Thomas Pornin
  • 322,884
  • 58
  • 787
  • 955
  • Sorry... hit enter accidentally. Thanks for the quick response. Is there a reason you recommend using the "|" separator instead of just concatenating the two strings together? Also, if I were to go with your recommendations above and also switch to SHA-512 and potentially also use Bcrypt or Scrypt... Do you see any issues with using this on 2 different sites with different site names (and the same email and password)? Would that generate a sufficient enough different "salt" to render the hashes fairly safe? – user44821 Apr 16 '14 at 22:05
  • Consider user 'bob' on site 'bysoft.com` vs user 'bobby' on site 'soft.com`. Both cases would end up with the same pseudo-salt. The separator character is a cheap way to avoid such cases. – Thomas Pornin Apr 16 '14 at 22:22
  • From my experience in cryptography, I would be very surprised if there was a problem with using the same password with distinct hash functions and distinct hash names. This would be a very unexpected structural relation between these hash functions. This is not a _proof_ but that does not seem overly unsafe to me. – Thomas Pornin Apr 16 '14 at 22:24
  • Hi Thomas.. thanks again for your prompt replies. Just to clarify, I meant I would switch to using SHA-512 for both sites, the only difference being that the "salt" would be different due to the site names being different. – user44821 Apr 17 '14 at 00:44