NYCPHP Meetup

NYPHP.org

[nycphp-talk] Thoughts on encryption

tedd tedd.sperling at gmail.com
Fri May 7 12:06:42 EDT 2010


>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



More information about the talk mailing list