
Originally Posted by
AliHurworth
Hi just a research question: I'm converting a new user and storing the email as a MD5 in order to get them to check in.
It occurs to me that I could use other values at the same time (so a hashed version of email, postcode and name). This would make it very much more secure
How would I do this?
Using a MD5 hash by itself is not secure enough for short strings like emails. Especially because the username is typically 1-10bytes of ASCII (some institutions I know of require email usernames under 8characters). The domain name exists in a public list of MX records. My cheap machine can make 3million+ attempts at an MD5 hash per second, probably less because I would need to concatenate combinations of MD5(guess + "@" + domain name).
That is why you should also include a very strong secret salt when generating a MD5 hash.
MD5(guess + "@" + domain name + secret salt).... forget brute forcing that, time to find another way in
But lets not be stupid and make a weak hash out of email.
In general MD5 hash is already outdated; collisions have been found (a long time ago).
JH and Skein both look like promising algorithms for the NIST SHA3 competition.
-----
In the meantime we'll cross our fingers and user MD5.
Lets look at using it in a mySQL query:
Code:
mysql> CREATE TABLE user (
-> user_ID int(11) PRIMARY KEY AUTO_INCREMENT,
-> userName varchar(50),
-> userHash varchar(20)
-> ) ENGINE=myISAM;
mysql> ALTER TABLE user
-> ADD UNIQUE (userName);
mysql> ALTER TABLE user
-> ADD UNIQUE (userHash);
the hash must be unique otherwise you have a collision.
PHP Code:
$sqlResource =
mysqlquery(
sprintf("SELECT user.user_ID
FROM user
WHERE MD5(%s%s%s%s) = user.userHash",
$userName, $email, $password, "This is a secret salt, it should be kept private."
)
);
if (mysql_num_rows($sqlResource)) {
$user = new User(mysql_fetch_object($sqlResource));
}
But this might not be secure depending on where your mySQL server is located. PHP also has a MD5 function, you may want to preprocess the hash before sending it to mySQL. I believe it's MD5().
I would also suggest you use SSL to receive the credentials through $_POST.
If a valid email is all you need for authentication then you don't really have enough credentials. Most places require an email/username and a strong password.
Maybe wait on Criterion9 to respond
hes good with these things.
Edit: I noticed this code will also have a problem with mysql handling the hash as a string. You should preprocess it with PHP first, that way people can use special characters that would otherwise mess up the query.
Bookmarks