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
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.
Last edited by eval(BadCode); 01-23-2011 at 01:07 AM.
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?
Assuming you've already done sanity checks on the values, I'd do this like:
PHP Code:
$prehash=$email.$postcode.$name;
$hash=md5($prehash);
// do whatever you want with the hash
When they come back, I'd hope you also require a password that is also stored as a salted hash. Then you compare data to the stored data
PHP Code:
$hash=$email.$postcode.$name;
$stored_hash=somefunction(); //get the hash out of the database
if ($hash==$stored_hash)
{
$password_authenticated=somepasswordfunction(); //validate the password using the correct hashes
if($password_authenticated)
{
echo('Welcome Back');}else{echo('Login attempt failed.');
}
}
Bookmarks