Possible Duplicate:
How to securely hash passwords?

How can I store passwords to have them secure? Right now the site use md5 md5, I was thinking about sha1+salt but if the source code for the site will be open source (I'm rewriting the site and the code will be on gihub) everybody will know what the salt is.

So how can I secure passwords so they will not be easy cracked when the database leak? Any ideas?

  • 1
    +1 for @Polynomial's link. Shameless plug, but i wrote a blog post on password storage: securityramblings.wordpress.com
    – user10211
    Jul 30 '12 at 14:33
  • 1
    A good security implementation doesn't depend on obscurity. It shouldn't matter if people are able to read your code.
    – user10211
    Jul 30 '12 at 14:34
  • 1
    @jcubic you are misunderstanding the purpose of the salt. Salts should not need to be hidden.
    – user10211
    Jul 30 '12 at 14:45
  • 1
    the point of a random salt per pw in the db is so they cant crack all your passwords in one run Jul 30 '12 at 14:45
  • 3
    Read my blog post, read through the links Polynomial posted. You have a lot of misconceptions about password hashing/storage. There is a lot of information on this topic in this site and around the web. I suggest you actually understand the topic before trying to design a secure authentication system.
    – user10211
    Jul 30 '12 at 14:50

A proper cryptographic implementation does not rely on obscurity. It should still hold up even when the methods of hashing and/or encryption are known, so long as the key (e.g.: password) is still protected.

As others have pointed out, you should not be using a static salt for your password database. This would quite nearly defeat the purpose of a salt, by enabling an attacker to pre-compute a rainbow table that will be useful against a large number of passwords.

Instead, each password should have a unique salt which is randomly generated when the account is created. The method for generating the salts, and for hashing the passwords, may be public. The salts and password hashes should be kept in a secured database.

This is not a panacea, however. You still must take appropriate measures to protect the confidentiality of the password database. Of course, if your site is vulnerable to SQL injection, the password database could be taken. And then, of course, it's only a matter of time before all passwords are cracked regardless of the salting or hashing mechanism.

The per-user, unique salt doesn't entirely prevent the password from being compromised. It only delays it by adding another element to the process which an attacker will not have foreknowledge of. Compare the following scenarios:

  • Unsalted hash: The attacker could already have a pre-computed rainbow table for your hashing mechanism, and may have all passwords cracked within the same day of retrieving the database.
  • Static salt (public or private): Once the static salt is known (either via inclusion in open source code, or system compromise), the attacker only needs to generate one rainbow table in order to break any password in your database. I'm not much familiar with how these things go, but it seems like it might be something worth waiting for if the target password database is fairly large or protects something of real value.
  • Unique salt, securely stored: No amount of pre-computation can be expected to work effectively against this, unless the attacker has an inconceivably large database containing rainbow tables for all possible salts. Absent that, the attacker will have to brute-force each password individually. Given a proper cryptographic implementation, this will likely take more time than the attacker, or any of his foreseeable descendants, can afford.

There's a lot of good guidance in the answers and comments here. I strongly suggest you look into it. Also, remember Rule #1 of Cryptography: Don't roll your own crypto.

  • What about if I store one big random text that I will use along with passwords hash(big_random_string + password), the the string will be on the disk (I already have one file that will not be in github - the file that contain database password). It will prevent brute force, and no one will be able to create rainbow table.
    – jcubic
    Jul 30 '12 at 15:12
  • @jcubic See scenario #2. Note that I said "public or private". If the code is open source, then the attacker knows where you store your hashes and your salts. If the system is otherwise inherently vulnerable, the attacker can still retrieve the salt - possibly as easily as he does the password hashes.
    – Iszi
    Jul 30 '12 at 15:17
  • I'm thinking only about scenario when someone will get the database via some stupid SQL injection.
    – jcubic
    Jul 30 '12 at 15:45
  • @jcubic with that attitude people are bound to hack your website. The only secure way is number 3 Jul 30 '12 at 18:24
  • I personally prefer using unique salts and a static salt. In the event that your database is leaked but the place (config file or such) in which you store your static is not, attackers still won't be able to achieve anything. It's a slight improvement, but an improvement nonetheless. Jul 30 '12 at 19:18

Ideally, you should be generating a random salt for each user account and storing the salt in the database. While the code to generate the salts could be public, the salts themselves should not.

Most web frameworks have a standard and usually secure way built-in for storing passwords, so best thing is to research before you implement something from scratch.

This will save you not only time but also most likely will be more secure than your own implementation, particularly if you have little experience in writing security-specific code.

  • Did anyone else just hear Rule #1 of Crypto in here?
    – Iszi
    Jul 30 '12 at 14:39
  • But if person have access to database, he can read the code and see where I store salt and how (I can't hide it), so he can get it from database too.
    – jcubic
    Jul 30 '12 at 14:39
  • @jcubic - If the person has access to the database then of course they can read the salt, as well as the hashed version of the password, and everything else you might store in there. But are you trying to protect against your own users? i.e. the people who would be running your code??
    – Yoav Aner
    Jul 30 '12 at 14:43
  • 1
    @YoavAner Essentially, yes. Don't roll your own crypto. Also, like that which must not be discussed, it's Rule #2 as well.
    – Iszi
    Jul 30 '12 at 14:44
  • 1
    Read @TerryChia's comments. I agree with him that you appear to hold a few misconceptions which might be difficult to explain all at once. The short of it - there are plenty of open-source projects that implement websites/web-frameworks and do this securely. Try to look-up how they do it and you can learn a lot without having to re-invent the wheel or implement your own crypto.
    – Yoav Aner
    Jul 30 '12 at 15:03

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