Programming C, C++, Java, PHP, Ruby, Turing, VB
Computer Science Canada 
Programming C, C++, Java, PHP, Ruby, Turing, VB  

Username:   Password: 
 RegisterRegister   
 How to really make a secure login.
Index -> Programming, PHP -> PHP Submissions
View previous topic Printable versionDownload TopicRate TopicSubscribe to this topicPrivate MessagesRefresh page View next topic
Author Message
pyrnight




PostPosted: Tue Dec 18, 2007 10:25 pm   Post subject: How to really make a secure login.

This is a secure php login based on using a salt to add security to hashes. Of course sha1 would be a algorithm to use here, but for simplicity I will leave it out.

How this works is like this:

When the user registers for the page, they are given a long, and randomly generated "Salt", that is unique to their username. The salt is then added to the password, then all that is hashed. If your password was ABC123, a bruteforcer will get that pretty easily if your md5 hash was discovered. Now, if your hash was ABC1239ga8932ti9hgga9831h8, it would probably take a few million years to bruteforce that hash. Many sites use this technique, but the problem is, if you "salt" (added part of the password which is then hashed) is the same for all your users, then all it takes is for the attacker to find out your salt, and then he instantly has all of your users.

Having a random salt unique to each user would make cracking a large list of usernames and passwords almost total impossible, and not worth the effort to even try. I could almost give away passwords generated by this, and because they don't know each individual salt, they would never find the plaintext password.

I hope this all makes sense. If you are unclear about something just ask Very Happy


Register.php

php:

$rUser = strip_tags($_REQUEST['u']); // username
$rPass2 = md5(substr($_REQUEST['p2'],0,50) . $rSalt); // password - add randomized salt, this salt is inlcued with other user info
$rEmail = strip_tags(stripslashes($_REQUEST['e']));

// This is the important part here
// This is the important part here
// This is the important part here
// This is the important part here
$rSalt = md5(rand(1,500000));
$rPass = md5(substr($_REQUEST['p'],0,50) . $rSalt); // password - add randomized salt, this salt is inlcued with other user info


// Then all this is put into a database after being sanitized and validated





Login.php

php:

<?php

include("sql.php"); // Your SQL connection file, basic stuff
session_start();

// Array to hold errors, at the end if there are no errors, then the finalizations are executed
$errors = Array();

$lUser = strip_tags($_REQUEST['u']); // username
$lPass = $_REQUEST['p']; // password

// Check if the username exists
$result = @mysql_query("SELECT * FROM `users` WHERE `name` = '$lUser' limit 1");
if(@mysql_num_rows($result) < 1)
{
        $errors[] = "Account does not exist.";
}

// Get salt, check password
$uSalt = @mysql_result($result, 0, 'users.salt'); // get the "salt" field
$password = md5($lPass . $uSalt); // calculate password with salt

// Check in the database if there is a username corresponding to the password hash we just calculated
$result = @mysql_query("SELECT * FROM `users` WHERE `name` = '$lUser' and `pass` = '$password' limit 1");
if(@mysql_num_rows($result) < 1) // no results found
{
        $errors[] = "Invalid Username or Password.";
}

// All error finding is done
if(count($errors) == 0)
{
        // set sessions
        $_SESSION['name'] = $lUser;
        $_SESSION['pass'] = $password;
       
        header("Location: game/index.php");
       
}
else
{
        // Print errors
        echo "The following errors occered: <br /><br />\n";
        showErrors($errors);
        echo "<br /><br />";
}

?>
Sponsor
Sponsor
Sponsor
sponsor
Dan




PostPosted: Tue Dec 18, 2007 11:27 pm   Post subject: RE:How to really make a secure login.

Not bad, however there are some redunceys. Why are you caluating the password 2 times in Register.php? If you asked the user to enter the password and then confrim the password again, this check should be done in plain text and if it is right a salted hash should be made.

Also in Login.php you should not need to make the 2nd query as the 1st one whould allready have the correct password hash in it and you could comapre it rather the do a search for it.


Now some tips to make it more secure:

1. Use SHA1 rather then MD5, it takes longer to crack a SHA1 hash. (as you noted)

2. Do not say why the login failed, this whould let an attacker know if an account exitces or not if they are using burte force.

3. In adtion to a random salt that is stored in the database you could also have one that is constant in the code so an atacker whould need both the code and the database to try any cracking of the hash.

4. Althought a user should probly not be able to see there seesion data, it is still probly best not to store there hashed password in the session. Rather i like to store the primary key for the user table and some kind of session id/key (unless php automakes one) as it makes the SQL selects on other pages faster and can not be used for evil if there is some bad session code or secuirty issue with sessions down the road.


Note: the random salt your code makes is NOT gratiened to be unique to each user as you claim, however this is not a big issue in terms of securtiy.
Computer Science Canada Help with programming in C, C++, Java, PHP, Ruby, Turing, VB and more!
PaulButler




PostPosted: Tue Dec 18, 2007 11:58 pm   Post subject: RE:How to really make a secure login.

Good stuff. I noticed you used $rSalt before you declared it in register.php, might want to have a look at that Wink.

A hacker who finds out the salt, though, will not really have instant access to all the passwords, he would still have to brute force it Smile. The real advantage that your method has is that the hacker couldn't just generate a list of common passwords and their hashes to compare with the database, he would have to generate that list for each different salt which would take a lot longer.
pyrnight




PostPosted: Wed Dec 19, 2007 5:44 pm   Post subject: RE:How to really make a secure login.

Oh yeh, I did do that, thats not the original code, I moved stuff around to try and make it more clear. Thanks, I'll edit that.

To Dan:

1. Yep
2. I guess so, but this is secure enough that it really don't matter, but you are right, it is better practice so give away less information.
3. I guess, but that seems kind of overkill. I could make it generate new salts for people daily or every time they log in, but again... that is just overkill.
4. I think thats just totally unnecessary. If people could see their sessions, it wouldn't be a session.... it would be a cookie...
Tony




PostPosted: Wed Dec 19, 2007 6:12 pm   Post subject: RE:How to really make a secure login.

"security" is a function of effort it takes to compromise the said security. "Overkill" is understood only in the context of the data and/or system you are trying to secure. Considering that the example is a game, it might be an overkill to even salt the passwords.
Latest from compsci.ca/blog: Tony's programming blog. DWITE - a programming contest.
Dan




PostPosted: Wed Dec 19, 2007 6:15 pm   Post subject: Re: RE:How to really make a secure login.

pyrnight @ 19th December 2007, 5:44 pm wrote:

2. I guess so, but this is secure enough that it really don't matter, but you are right, it is better practice so give away less information.


It has nothing to stop brute force atacks, so giving away that information aucatly does drastickly effect the time a burt force attack whould take.

pyrnight @ 19th December 2007, 5:44 pm wrote:

3. I guess, but that seems kind of overkill. I could make it generate new salts for people daily or every time they log in, but again... that is just overkill.


There is no way you could generate a new salt for a user ever again unless you change there password, you kept there password in plain text (witch deaftes the hole propse) or you crack there hash. If you only have a salt in the database then you only need the database to start an attack on the hash. Peoleop have made hardware impmentations of md5 crackers that can get most hashes in at least a day and with our current level of computer power it is becoming easyer every day. Knowing the salt reduceds the search space drasticly when doing a brut force atack on the hash.

pyrnight @ 19th December 2007, 5:44 pm wrote:

4. I think thats just totally unnecessary. If people could see their sessions, it wouldn't be a session.... it would be a cookie...


I am not trying to say that peoleop can noramly see there sessions, i am saying there is no need to put a passwrod in the session and that you are tursting that every script on your server is going to be secure to keep that password secure. Also some webservers and programs log the session data to a log, this whould mean you now have the password in a log file and in the database. So why go out of your way to duplicate data you whont secure?


Also to make this even more secure it can be done threw SSL so no one can use a packet scanner to get the plain text password befor it makes it to the webserver. Tho that whouls normaly be indpent of the code for the login.
Computer Science Canada Help with programming in C, C++, Java, PHP, Ruby, Turing, VB and more!
md




PostPosted: Wed Dec 19, 2007 6:36 pm   Post subject: RE:How to really make a secure login.

I'm not seeing the advantage over a secret, but static salt for all passwords. If the salt is secret to everyone except those with access to the source (command line, or an exploit, etc.) then it's just as secure as a random salt stored in a database; better even depending on how the database is secured and the site designed. It's rare to be able to gain access to source code through exploits; but SQL injection is fairly common.
Dan




PostPosted: Wed Dec 19, 2007 7:03 pm   Post subject: Re: RE:How to really make a secure login.

md @ 19th December 2007, 6:36 pm wrote:
I'm not seeing the advantage over a secret, but static salt for all passwords. If the salt is secret to everyone except those with access to the source (command line, or an exploit, etc.) then it's just as secure as a random salt stored in a database; better even depending on how the database is secured and the site designed. It's rare to be able to gain access to source code through exploits; but SQL injection is fairly common.


I am saying to use both static in code and random per user in database.
Computer Science Canada Help with programming in C, C++, Java, PHP, Ruby, Turing, VB and more!
Sponsor
Sponsor
Sponsor
sponsor
PaulButler




PostPosted: Wed Dec 19, 2007 8:33 pm   Post subject: Re: RE:How to really make a secure login.

md @ Wed Dec 19, 2007 6:36 pm wrote:
I'm not seeing the advantage over a secret, but static salt for all passwords.


The only advantage I see is that if someone were to get their hands on the database, if they wanted the password for each user, then they could brute force all the passwords at the same time, rather than brute forcing every single one.

An example in practice:

Everyone in Tim's company has a username and password for a Novell log in. Tim is asked to write a web app for something or other. Since the company's IT department is rather backwards (remember, they use Novell), they don't want the app to use the Novell server for authentication, but to instead get the password from a database. Obviously they don't want to give Tim all the passwords, so they hash and salt them. Since Tim is a poor coder, a hacker gets access to the database. The hacker knows he can cause a lot of damage just by getting a single password, since the password gives him access not only to the web app but also to company email.

If the passwords in the database use a static hash, the hacker can try hashing common dictionary words with the salt and see if any of them fit.

On the other hand, if the passwords each use their own hash, the hacker has to do a lot more dictionary attacks to get a working account.
PaulButler




PostPosted: Wed Dec 19, 2007 8:36 pm   Post subject: Re: RE:How to really make a secure login.

[quote="Dan @ Wed Dec 19, 2007 6:15 pm"]
pyrnight @ 19th December 2007, 5:44 pm wrote:

I am not trying to say that peoleop can noramly see there sessions, i am saying there is no need to put a passwrod in the session and that you are tursting that every script on your server is going to be secure to keep that password secure. Also some webservers and programs log the session data to a log, this whould mean you now have the password in a log file and in the database. So why go out of your way to duplicate data you whont secure?


Dan has a good point here. Sessions are stored in flat-files in (I think) /tmp by default. If you are using a poorly configured shared server, anyone else with an account on the server can access your sessions.

That said, I still use sessions, but it is something to consider if you are on a shared server.
pyrnight




PostPosted: Fri Dec 21, 2007 6:10 pm   Post subject: Re: RE:How to really make a secure login.

PaulButler @ Tue Dec 18, 2007 11:58 pm wrote:
Good stuff. I noticed you used $rSalt before you declared it in register.php, might want to have a look at that Wink.

A hacker who finds out the salt, though, will not really have instant access to all the passwords, he would still have to brute force it Smile. The real advantage that your method has is that the hacker couldn't just generate a list of common passwords and their hashes to compare with the database, he would have to generate that list for each different salt which would take a lot longer.




Well if i had an SQL injection exploit, I could just sign up with no password, of a very simple password, and then bruteforce the salt. Of course the length of the salt would come into play, but yeh, this is over-secure, but thats good.
Tony




PostPosted: Fri Dec 21, 2007 8:16 pm   Post subject: Re: RE:How to really make a secure login.

pyrnight @ Fri Dec 21, 2007 6:10 pm wrote:
Well if i had an SQL injection exploit, I could just sign up with no password, of a very simple password, and then bruteforce the salt.

and that is why one validates their objects, not just on save, but on load as well.
Latest from compsci.ca/blog: Tony's programming blog. DWITE - a programming contest.
PaulButler




PostPosted: Sat Dec 22, 2007 11:07 am   Post subject: Re: RE:How to really make a secure login.

pyrnight @ Fri Dec 21, 2007 6:10 pm wrote:
PaulButler @ Tue Dec 18, 2007 11:58 pm wrote:
Good stuff. I noticed you used $rSalt before you declared it in register.php, might want to have a look at that Wink.

A hacker who finds out the salt, though, will not really have instant access to all the passwords, he would still have to brute force it Smile. The real advantage that your method has is that the hacker couldn't just generate a list of common passwords and their hashes to compare with the database, he would have to generate that list for each different salt which would take a lot longer.




Well if i had an SQL injection exploit, I could just sign up with no password, of a very simple password, and then bruteforce the salt. Of course the length of the salt would come into play, but yeh, this is over-secure, but thats good.


The salt should not be short enough that it is easy to brute force. A number between 1 and 500000 is not that hard to brute force (on average it would take 250,000 tries), but if you used md5(uniqid(rand(), true));, it would be pretty hard to brute force because it would give you a 32 byte salt, so it would take on average 2^255 tries to brute force.
Display posts from previous:   
   Index -> Programming, PHP -> PHP Submissions
View previous topic Tell A FriendPrintable versionDownload TopicRate TopicSubscribe to this topicPrivate MessagesRefresh page View next topic

Page 1 of 1  [ 13 Posts ]
Jump to:   


Style:  
Search: