Hi Anthony, MD5 and SHA1 password hashes are considered weak. You are correct that someone got a hold of your hashes they could use a dictionary of common passwords to devise some of your user's passwords.There are a few ways to deal with this. The simplest is to just force users to create complicated passwords. Make them use passwords that are at least 8 characters and contain at least one digit and one non-alphanumeric character. This makes a dictionary attack much less practical (but by no means impossible if you have a lot of resources). The other way is to use a hashing algorithm with a larger bitwidth. Another is to add a salt. Better still, use all of these techniques. One pedantic note: MD5 and SHA1 are not encryption algorithms. They are hashing algorithms. With encryption you take plaintext and convert it to ciphertext and then you can do the reverse and get the plaintext back. With hashing you take plaintext and convert it to a hash which is just a random bit of data but of course given the same input you always get the same output. But with a hash you cannot convert it back to plaintext. Personally I recommend that you do not invent your own hashing algorithm. It only creates an opportunity to make a mistake that can be exploited and it does not increase security anywhere near as much as increasing the bitwidth. Just use a standard hashing method so that passwords can be migrated, code is understood and can be ported, etc. I would recommend using SSHA256 which is computed as follows: 1. Convert the plaintext password to UTF-8. In PHP you can use iconv for this. 2. Generate an 8 byte random salt. In PHP you can use mt_rand for this. 3. Generate the SHA256 hash of the UTF-8 plaintext password + salt. In PHP 5 you can use hash_init('sha256'), then hash_update($utf8password) followed by hash_update($salt) and hash_final to get the hash. 4. Concatenate the hash followed by the salt, convert the result to Base64 and then prefix it with the "{SSHA256}" label to get a result that looks like: {SSHA256}1LzicRO5StQs9kSR4UvTZbgfyhiiknzwDUhKaAgXUEa1uyL/s1Pd/A== Here's an example with real values and salt used so that you can check your computations as you go: Plaintext: opensaysme Salt in Hexadecimal: B5 BB 22 FF B3 53 DD FC SHA256 Hash of Plaintext and Salt in Hexadecimal: D4 BC E2 71 13 B9 4A D4 2C F6 44 91 E1 4B D3 65 B8 1F CA 18 A2 92 7C F0 0D 48 4A 68 08 17 50 46 SSHA256 Text Representation (this is what you put in the DB): {SSHA256}1LzicRO5StQs9kSR4UvTZbgfyhiiknzwDUhKaAgXUEa1uyL/s1Pd/A== Note that even though I show the values in hex for the purpose of this message, all of the computations are done using binary which means in PHP you're going to need to write helper functions that use ord and chr quite a bit. This 256 salted password hash is standard and is understood by software like LDAP servers. Combined with complex password requirements, this would disappoint even a serious cracker. If your system does not support sha256, do SSHA128 instead using the sha128 algorithm (aka sha1) + salt. Otherwise it is computed in exactly the same way but of course it will only be 128 bits instead of 256. But at least you'll have a salt which will greatly slow down a dictionary attack. Mike
And even more excellent advice -- my notes on this are overflowing. Cheers, tedd -- ------- http://sperling.com http://ancientstones.com http://earthstones.com _______________________________________________ New York PHP Users Group Community Talk Mailing List http://lists.nyphp.org/mailman/listinfo/talk http://www.nyphp.org/Show-Participation
