-1

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?

jcubic
  • 209
  • 3
  • 11
  • 1
    +1 for @Polynomial's link. Shameless plug, but i wrote a blog post on password storage: http://securityramblings.wordpress.com/ –  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. –  Jul 30 '12 at 14:34
  • See also: http://security.stackexchange.com/questions/17421/how-to-store-salt / http://security.stackexchange.com/questions/4781/do-any-security-experts-recommend-bcrypt-for-password-storage / http://security.stackexchange.com/questions/5605/which-password-hashing-method-should-i-use / http://security.stackexchange.com/questions/12298/password-security-in-databases-today-still-best-practice – Polynomial Jul 30 '12 at 14:34
  • @Polynomial if the site is open source I can't hide the salt, am I? If I store it in database person that use SQL ijection will get it too, and also he don't need to guess how database look like. – jcubic Jul 30 '12 at 14:42
  • 1
    @jcubic you are misunderstanding the purpose of the salt. Salts should not need to be hidden. –  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 – Lucas Kauffman Jul 30 '12 at 14:45
  • @TerryChia If I use hash that no one can guess from database, it will be secure, If the site is open it will be not because the person will know what hash I use. It will be more secure if person that get access to database don't know if I use md5 2 md5 or sha1 (if I add few letter so md5 look like sha1), If the code will be open source person will know that I use md5 with random letter, so it's the same as only md5. – jcubic Jul 30 '12 at 14:48
  • 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. –  Jul 30 '12 at 14:50
  • I always thought that salt is used to prevent bruteforce attacks (if passwords have 3 letter it will be easy to crack but when I add random text with 20 letter to password before I hash it, it will prevent bruteforce becasue it will take years to crack. – jcubic Jul 30 '12 at 15:15
  • @jcubic Salts don't prevent brute force - nothing can *prevent* brute force. What salts do is nullify the effectiveness of rainbow tables, which *greatly* accelerate the brute force process. However, having a static salt that is the same for all passwords is not much better than having no salt at all. – Iszi Jul 30 '12 at 15:21
  • @Iszi but If I have password foobar (6 letters) and I store hash("<___LONG_STRING___>_foobar") (26 letters) and they only get the hash, it will be the same as I have 26 letter password. – jcubic Jul 30 '12 at 15:33
  • @jcubic Yes, but if your system is weak enough to give up the hash then you must presume it is also weak enough to give up the salt. Then, you're back down to a 6-letter password. – Iszi Jul 30 '12 at 15:38
  • @Iszi I can store that salt in the file, it will be the same as database password that I don't hold in the repo. – jcubic Jul 30 '12 at 15:42
  • @jcubic - The fact you are using MD5 to protect the password currently means that, giving your typical 10 character password, it would be a trivial task to brute force the password. YOU SHOULD NOT USE MD5 to hash a password. Even SHA1 is not the best choice because of how it works you should be using password hasing mechanic. – Ramhound Jul 31 '12 at 12:56

2 Answers2

6

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.

Iszi
  • 27,027
  • 18
  • 99
  • 163
  • 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 – Lucas Kauffman 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. – AardvarkSoup Jul 30 '12 at 19:18
  • @jcubic - The fact you are currently using MD5 to hash passwords should concern you. Everything you know about security is WRONG based on that fact. – Ramhound Jul 31 '12 at 12:57
  • @Ramhound I didn't choose to use md5, other people create it this way. – jcubic Jul 31 '12 at 15:11
3

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.

Iszi
  • 27,027
  • 18
  • 99
  • 163
Yoav Aner
  • 5,329
  • 3
  • 25
  • 37
  • 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
  • @iszi - what's rule #1 of Crypto? (don't re-invent the wheel?) – Yoav Aner Jul 30 '12 at 14:44
  • 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
  • @iszi - totally agree. I tried to explain it as clearly as I could to the OP (but thanks for the edit!)... this also applies to software-development in general (the DRY principle I suppose, in this case no point trying to solve problems others have already solved for you) – Yoav Aner Jul 30 '12 at 14:47
  • @YoavAner it will be opensource so they can contribute to the site, fix bugs, add new features, fork+pull requests and stuff. We are also thinking about giving database without user data (or hashes), so the users will be able to test it localy. – jcubic Jul 30 '12 at 14:57
  • 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