Jump to content

Php Password Hash Tutorial

Whether you're a seasoned veteran or a struggling beginner, Web Radiance is the web development and web design forum for you. You'll find answers to all your HTML, CSS, SEO, and Programming needs. Pull up a chair and stay awhile.

Page 1 of 1
  • You cannot start a new topic
  • This topic is locked

Php Password Hash Tutorial Rate Topic: -----

#1 User is offline   Photoshop 

  • W.R. Private
  • Group: Members
  • Posts: 5
  • Joined: 21-December 10

Posted 21 December 2010 - 02:45 PM

For security reasons its always better to hash your passwords.. You can possibly get away with md5() but why not add an extra step?
This is a function that will encrypt your passwords much better than just md5ing them.

Usage: Add this to your file and then simply use ion_passwd() instead of md5().
function ion_passwd ($var) {
	$var = str_replace('"',"",$var);
	$var = str_replace("'","",$var);
	$var = str_replace('`',"",$var);
	$var = str_replace('|',"",$var);
	$var = str_replace('%',"",$var);
	$var = str_replace('--',"",$var);
	$var = str_replace('/',"",$var);
	$var = stripslashes($var);
	$var = strip_tags($var);
	$origvar = $var; 
	$var = sha1($origvar);
	$salt = substr($var,0,4);
	$var = ($origvar.$salt);
	$var = sha1($var);
	return $var;
};


Ok So lets look at what this does exactly..

Says Hey! Im making a new function!
function ion_passwd ($var) {


Replaces certain characters and strips slashes/html.
	$var = str_replace('"',"",$var);
	$var = str_replace("'","",$var);
	$var = str_replace('`',"",$var); // ("character to look for","blank quotes so it replaces the characters with nothing","$var Gets automatically replaced with whatever variable you run through it")
	$var = str_replace('|',"",$var);
	$var = str_replace('%',"",$var);
	$var = str_replace('--',"",$var);
	$var = str_replace('/',"",$var);
	$var = stripslashes($var);
	$var = strip_tags($var);


Keep a clean copy of the actual password.
$origvar = $var; 


sha1() The password, then only keep 4 characters, these are added to the actual password to make it harder to break.
$var = sha1($origvar);
	$salt = substr($var,0,4);
	$var = ($origvar.$salt);


Then finally it encrypts the password with its salt.
$var = sha1($var);
	$var = substr($var,0,30);
	return $var;


Example..

Password: '<b>%%lTest32//\\'
Clean Password: lTest32
RESULT:
f96c64dda78bd4c0dc0509d2c418204763e78eea


Feel free to post any comments, suggestions and so on.

Update: You should always clean your variables, I just added that part to the function so you could all see how to do it.

-IOn Photoshop

This post has been edited by Photoshop: 22 December 2010 - 12:15 PM

0

#2 User is offline   temhawk 

  • W.R. Private First-Class
  • Group: Members
  • Posts: 322
  • Joined: 30-August 07
  • Gender:Male
  • Interests:travel, cg art, macs, music, skateboarding, programming, discovery channel, TextMate 2

Posted 21 December 2010 - 08:29 PM

Hi, I'm a security-newbie (my sites can probably be hacked in a hundred different ways right now) so I thought I'd read this tutorial to make a small step in the right direction. One thing I don't understand is why you replace some characters. If the users enters them as part of the password, and you change it on submit, how does he know what characters are replaced? And isn't it rather odd behavior? Because I expect sites to accept any characters I choose as my password.
0

#3 User is offline   Photoshop 

  • W.R. Private
  • Group: Members
  • Posts: 5
  • Joined: 21-December 10

Posted 22 December 2010 - 06:12 AM

You don't want to let them use certain characters. Example, if I put " or ' in my password that can mess up the script.
0

#4 User is offline   temhawk 

  • W.R. Private First-Class
  • Group: Members
  • Posts: 322
  • Joined: 30-August 07
  • Gender:Male
  • Interests:travel, cg art, macs, music, skateboarding, programming, discovery channel, TextMate 2

Posted 22 December 2010 - 06:27 AM

I thought you can escape those characters to make them safe. (I haven't tested it myself.) :confused1:
0

#5 User is offline   Photoshop 

  • W.R. Private
  • Group: Members
  • Posts: 5
  • Joined: 21-December 10

Posted 22 December 2010 - 06:52 AM

"sanitising or cleaning a variable is standard practice to ensure that a variable used within a page or even within a dynamic SQL query is clean from any nasties which would cause harm to the script or database."

Its just added on safety if you want to allow them to use those characters your free to remove that part.

PHP also has a function that might help you called mysql_real_escape_string() you should look into it, I found you a page on it since I was reading about it anyway. http://php.net/manua...cape-string.php
Definitely look into it :)
0

#6 User is offline   temhawk 

  • W.R. Private First-Class
  • Group: Members
  • Posts: 322
  • Joined: 30-August 07
  • Gender:Male
  • Interests:travel, cg art, macs, music, skateboarding, programming, discovery channel, TextMate 2

Posted 22 December 2010 - 09:29 AM

So I can keep those characters (escaped) and still use your encryption technique, right? There is no extra security risk if I do it right, is there?
0

#7 User is offline   Rob Kaper 

  • W.R. Corporal
  • Group: Members
  • Posts: 97
  • Joined: 19-July 08
  • Gender:Male
  • Location:Rotterdam, NLD

Posted 22 December 2010 - 09:56 AM

Ouch.

1) You sanitize inside a hash generator, implying you don't do it elsewhere at worst (or duplicate code at best). You need to sanitize ALL user input ALL the time.
2) You sanitize with some simple replacements. Move over to mysql_real_escape_string immediately, it escapes what actually needs to be escaped including some of the less obvious control characters.
3) You use md5(), which is no longer considered a secure hash due to published collisions and rainbow (lookup) tables. Use hash() with a proper algorithm.
4) You trim the end result which creates even more collisions.

Salting the hash is pretty much the only thing you've done here to improve security.

This post has been edited by Rob Kaper: 22 December 2010 - 10:01 AM

Rob Kaper - Rotterdam
0

#8 User is offline   Photoshop 

  • W.R. Private
  • Group: Members
  • Posts: 5
  • Joined: 21-December 10

Posted 22 December 2010 - 12:00 PM

View PostRob Kaper, on 22 December 2010 - 09:56 AM, said:

Ouch.

1) You sanitize inside a hash generator, implying you don't do it elsewhere at worst (or duplicate code at best). You need to sanitize ALL user input ALL the time.
2) You sanitize with some simple replacements. Move over to mysql_real_escape_string immediately, it escapes what actually needs to be escaped including some of the less obvious control characters.
3) You use md5(), which is no longer considered a secure hash due to published collisions and rainbow (lookup) tables. Use hash() with a proper algorithm.
4) You trim the end result which creates even more collisions.

Salting the hash is pretty much the only thing you've done here to improve security.


You are right and wrong imo. I have a seperate function for that I just figured why not add it to show people how to do that kind of stuff.
Yes you create more collisions by trimming the end but at the same time online crackers are available for md5 hashes so why not stop them right there?

I do remember using sha1 instead of md5 for a while Im going to update the tutorial.

This post has been edited by Photoshop: 22 December 2010 - 12:17 PM

0

#9 User is offline   temhawk 

  • W.R. Private First-Class
  • Group: Members
  • Posts: 322
  • Joined: 30-August 07
  • Gender:Male
  • Interests:travel, cg art, macs, music, skateboarding, programming, discovery channel, TextMate 2

Posted 22 December 2010 - 12:23 PM

I don't know what collisions are, what rainbows are, not even sure about whether I know what a hash generator is. :notworthy: But I would like to know if it is necessary to remove any characters from user input at all, or if escaping it properly is all I need to prevent any kind of injected code or errors due to any such characters.
0

#10 User is offline   Photoshop 

  • W.R. Private
  • Group: Members
  • Posts: 5
  • Joined: 21-December 10

Posted 22 December 2010 - 12:31 PM

View Posttemhawk, on 22 December 2010 - 12:23 PM, said:

I don't know what collisions are, what rainbows are, not even sure about whether I know what a hash generator is. :notworthy: But I would like to know if it is necessary to remove any characters from user input at all, or if escaping it properly is all I need to prevent any kind of injected code or errors due to any such characters.


You definitely always want to remove certain characters. The thing is you want to always do this not just when your generating a hash.
0

#11 User is offline   Rob Kaper 

  • W.R. Corporal
  • Group: Members
  • Posts: 97
  • Joined: 19-July 08
  • Gender:Male
  • Location:Rotterdam, NLD

Posted 22 December 2010 - 01:53 PM

View Posttemhawk, on 22 December 2010 - 12:23 PM, said:

I don't know what collisions are, what rainbows are, not even sure about whether I know what a hash generator is. :notworthy: But I would like to know if it is necessary to remove any characters from user input at all, or if escaping it properly is all I need to prevent any kind of injected code or errors due to any such characters.


A hash generator converts a plain text string (in this case a password) to another string with one-way encryption. This new string is called the hash. You do this so that no passwords have to be stored and a leaked database wouldn't compromise user accounts. When users log in you would compare the hashes, not the password.

A collision means different strings (read: passwords) generate the same hash value. That reduces security because it speeds up brute force attacks significantly: hackers would have to find just one of the strings leading to a hash to break it, not specifically the one the user chose. Removing parts of the hash is bad for the same reason: in the above example we're effectively ignoring whether the last two characters of the hash match. We only check the first 30. This would protect us against lookups in hash tables, but salting already does that, so we gain nothing while making brute force attacks easier.

Rainbow tables are (in a very simplified view) a big list of hashes and known strings to generate each hash.

@Photoshop: I didn't want to sound harsh, I appreciate your effort. Reminding users to sanitize is very good but I wouldn't include it in a tutorial about something else, that was confusing. Especially because in this case it actually makes your function a lot weaker. In your example I could login with the password ITest32 into the account with password '<b>%%lTest32//\\'. Or an account with password I<i>Test32, or password ITest32", and so on and so on. Removing the sanitization and substr part actually makes your function a lot more secure. ;)
Rob Kaper - Rotterdam
0

#12 User is offline   Rob Kaper 

  • W.R. Corporal
  • Group: Members
  • Posts: 97
  • Joined: 19-July 08
  • Gender:Male
  • Location:Rotterdam, NLD

Posted 22 December 2010 - 02:11 PM

View PostPhotoshop, on 22 December 2010 - 12:31 PM, said:

You definitely always want to remove certain characters. The thing is you want to always do this not just when your generating a hash.


Crypt functions such as md5() don't need their input to be sanitized, so keep your code clean and simple and don't do it there. It's pointless at best and harmful (as explained in the previous post) at worst. The key secret to writing good code is to remove what's unnecessary.

But yes, you definitely always want to sanitize user input for SQL queries, file paths and data being sent to the browser (which might include unwanted HTML or Javascript). It's better to learn (or teach) what to sanitize and when than to increase complexity by sanitizing even strings that don't need to be.
Rob Kaper - Rotterdam
0

#13 User is offline   temhawk 

  • W.R. Private First-Class
  • Group: Members
  • Posts: 322
  • Joined: 30-August 07
  • Gender:Male
  • Interests:travel, cg art, macs, music, skateboarding, programming, discovery channel, TextMate 2

Posted 22 December 2010 - 11:36 PM

Thank you, Rob.

It's still not clear for me if "sanitizing" must mean actually removing some characters, or if it is just as secure to escape them (properly) whenever necessary so that the "user-visible" content doesn't change (so they could have SQL injection code in their submitted form, but it wouldn't work and when they view their submitted content on another page they see it the way they entered it and say "damn, this site is very secure!" :D )

I am also interested how the encryption like sha1 works. You say it's one-way, but if I encrypt only one character like "W" and my database is hacked, all the hacker has to do is encrypt "W" himself and he sees that the two hashes are the same so he now knows the "password". Hackers could make their own database of hashes beforehand, and when they hack a site's database all they have to do is match up the hashes. Or is my thinking wrong?

This post has been edited by temhawk: 22 December 2010 - 11:39 PM

0

#14 User is offline   Karl Buckland 

  • A.K.A. Sirkent
  • Group: Administrators
  • Posts: 2,145
  • Joined: 04-April 06
  • Gender:Male
  • Location:Kent, UK

Posted 23 December 2010 - 05:19 AM

Hi Temhawk. Your thinking is correct. You can build up databases of md5 hashes for popular passwords. It's possible to work out even very long complicated passwords, but generally it takes a long time and the number of possible permutations makes it impactical. But this is where using a salt comes into play. By using a salt (either site-wide or, preferably, a different salt for each user) you make the hash database effectively useless. Someone would need to generate a database including all possible permutations of salts, which would frankly be insane. This is why although md5 has been shown to be insecure, it's still secure enough when using salts.

When it comes to sanitizing I'm afraid this is a bit of a complicated issue. Generally it's best to remove some characters *and* escape them too, just to be sure. There are no doubt some PHP libraries out there to assist you in this. Personally, I like how the Codeigniter framework handles this and since it's open source, I re-use their implementation in any projects I write, even if they don't use the Codeigniter framework. However, I agree with Rob on this one. I don't see the point of sanitising input to a hash function. You want to ensure that you get the same hash back whether the code is written in PHP, .NET, Perl, etc. So making your password function as simple as possible is probably quite sensible. Using a decent hash function and salt should be enough. Anything more than that (including trimming the result, or removing characters) seems unnecessarily complicated and potentially problematic.

You can see the security code for Codeigniter here:
https://bitbucket.or...es/Security.php
Note the xss_clean() function as well as some of the sanitize functions. In most frameworks I've worked on, I think it's quite sensible to detect if the method for the request is 'POST' and then automatically clean up all incoming POST variables before executing the main code for the page. Occasionally this can cause issues if you're expecting very specific input, but for security I think it's wise. Generally this shouldn't add too much overhead to your requests, but if you're worried about it then you can manually clean your data before running SQL queries or working with files.
QUOTE(benbramz @ Aug 17 2007, 07:44 AM) Ive noticed that quite a few people are now adding quotes from the board into their signature. I think its started an new web-radiance craze.. :P
0

#15 User is offline   temhawk 

  • W.R. Private First-Class
  • Group: Members
  • Posts: 322
  • Joined: 30-August 07
  • Gender:Male
  • Interests:travel, cg art, macs, music, skateboarding, programming, discovery channel, TextMate 2

Posted 23 December 2010 - 06:28 AM

Thank you for explaining this to me. You have all been very helpful.

Would it add a little bit more security if I generate the password hashes on the client side with JavaScript? Then if someone hacks the SSL encryption they wouldn't immediately have the password. Or would that not matter anymore if they managed to get past SSL?
0

#16 User is offline   Karl Buckland 

  • A.K.A. Sirkent
  • Group: Administrators
  • Posts: 2,145
  • Joined: 04-April 06
  • Gender:Male
  • Location:Kent, UK

Posted 23 December 2010 - 08:23 AM

If someone hacks the SSL encryption, then the whole of the internet is screwed. Right now, it's not possible, so don't worry. I would say that generating the password hashes on the client side is a bit pointless, as you still have to send the hash to the backend. This means that if someone got hold of your hash (but not your password) they could still log in as you by sending that hash. You're also relying on the client as part of your security, which is an element you don't control. When programming anything security related I recommend you try to control as much of the process as possible.
QUOTE(benbramz @ Aug 17 2007, 07:44 AM) Ive noticed that quite a few people are now adding quotes from the board into their signature. I think its started an new web-radiance craze.. :P
0

#17 User is offline   temhawk 

  • W.R. Private First-Class
  • Group: Members
  • Posts: 322
  • Joined: 30-August 07
  • Gender:Male
  • Interests:travel, cg art, macs, music, skateboarding, programming, discovery channel, TextMate 2

Posted 23 December 2010 - 08:42 AM

Okay ^_^ thanks!
0

Share this topic:


Page 1 of 1
  • You cannot start a new topic
  • This topic is locked

1 User(s) are reading this topic
0 members, 1 guests, 0 anonymous users