Securing password at registration

  • (2 Pages)
  • +
  • 1
  • 2

28 Replies - 4835 Views - Last Post: 15 March 2012 - 08:34 AM Rate Topic: -----

#1 cxn  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 33
  • Joined: 10-March 12

Securing password at registration

Posted 10 March 2012 - 06:45 AM

Hi guys!

I've been browsing a lot of forums lately and I'm pretty much convinced that this is a great community which will improve my programming skills! I'm currently starting to learn PHP and MySQL. I've read a few books and I know the basics. The only problem is putting it all in practice.

I have a little project in my head, but I know this will take a lot of time. I decided to do it all step by step so I actually understand everything I do :-)

I was told to start with a registration and login form. I've also been told to use md5 to secure my passwords. However, on the PHP manual site I've read that this is not secure enough anymore to store passwords. I've read multiple alternatives but I still don't know which is best and which is most secure. And most importantly, which is suitable for me!

Basically I'm going to start with a three-column table:

ID --- USER --- PASSWORD

In my next step I am going to add a forth column, a boolean, to check whether the account has been verified or not. (however for now I'm gonna stick with the basics).

Problem number 1: So in my 3-column table I'm going to store a password. I'll be the only one having access to the mysql database, what kind of hashing or encrypting method do you guys recommend? Is MD5 in my case still safe 'enough'?

Problem number 2: If lets say I currently use a certain method (lets say MD5) and in the future I want to 'upgrade', will I have to let all my users choose a new password?

I hope I made myself clear, if not let me know and I will provide furter information.

Thanks in advance!
Bart

Is This A Good Question/Topic? 0
  • +

Replies To: Securing password at registration

#2 Atli  Icon User is offline

  • Enhance Your Calm
  • member icon

Reputation: 4238
  • View blog
  • Posts: 7,216
  • Joined: 08-June 10

Re: Securing password at registration

Posted 10 March 2012 - 06:59 AM

Hey!

For the first problem: MD5 is in fact very weak. It is no longer a good choice for hashing passwords. What I would recommend instead is one of the SHA2 algorithms. I personally prefer using SHA512, but SHA256 is probably enough for now. - The difference there is the size of the output hash:

  • MD5 produces a 128 bit (32 character) hash.
  • SHA256 produces a 256 bit (64 char) hash.
  • SHA512 produces a 512 bit (128 char) hash.


You'll have to adjust your database columns to fit the character length. For SHA512 you'd want to use CHAR(128), for example.

In PHP, you can create these hashes using the hash function. It's basically just as simple as:
$theHash = hash("sha512", $thePassword);
.


For the second problem, check out this tutorial by creativecoding:
- Update users passwords to a more secure hash, secretly

P.S.
You may also want to look into salting your hashes, to make them more secure. See:
- Introduction to Hashing

This post has been edited by Atli: 10 March 2012 - 07:02 AM

Was This Post Helpful? 2
  • +
  • -

#3 Dormilich  Icon User is offline

  • 痛覚残留
  • member icon

Reputation: 4138
  • View blog
  • Posts: 13,074
  • Joined: 08-June 10

Re: Securing password at registration

Posted 10 March 2012 - 07:07 AM

#1) even if only you have access, a successful SQL Injection attack will turn that upside-down. besides that, guess how many people post there database password in a help forum.

for the password hashing I can recommend 3 hash algorithms:
- RIPEMD-160
- SHA-256
- Whirlpool
there is no "best algorithm" per se. each one has its strong and weak points, but as lon as there is no known collision, it doesnít matter which you use.

if you want to strengthen security, add another column for the hash salt (used to prevent dictionary attacks). computing salted hashes is best done via hash_hmac().

#2) you donít. therefore it is essential to use a proper algorithm to begin with. and yes, using a different method would force all users to make a new password (thatís why you try not to do it)

PS. who for Peteís sake recommended to use MD5? its insecurity is known for such a long time that no one on his right mind would dare to use it in a critical situation.
Was This Post Helpful? 1
  • +
  • -

#4 cxn  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 33
  • Joined: 10-March 12

Re: Securing password at registration

Posted 10 March 2012 - 07:21 AM

Hello guys and thank you both for the quick response. I've read the article about salting. I'm pretty sure I'll be using SHA-256 on a salted string. I was wondering if salting at the end of the string is less secure than salting both at the beginnen and the ending of the string.

Another maybe silly question; my 3 table mysql database layout still holds, right?
With:

ID --- USER --- PASSWORD (but hashed/salted)

PS @ Dormilich: funny, a friend of mine studying computer science recommended MD5!
Was This Post Helpful? 0
  • +
  • -

#5 cxn  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 33
  • Joined: 10-March 12

Re: Securing password at registration

Posted 10 March 2012 - 07:31 AM

View PostDormilich, on 10 March 2012 - 07:07 AM, said:

if you want to strengthen security, add another column for the hash salt (used to prevent dictionary attacks). computing salted hashes is best done via hash_hmac().


Wouldn't storing the salt in my database undo the benefits of salting them? And do you mean every user has a different salt?
Was This Post Helpful? 0
  • +
  • -

#6 Dormilich  Icon User is offline

  • 痛覚残留
  • member icon

Reputation: 4138
  • View blog
  • Posts: 13,074
  • Joined: 08-June 10

Re: Securing password at registration

Posted 10 March 2012 - 07:48 AM

View Postcxn, on 10 March 2012 - 03:31 PM, said:

Wouldn't storing the salt in my database undo the benefits of salting them? And do you mean every user has a different salt?

no. a saltís purpose is to prevent Dictionary Attacks. it does not make a hash more secure. it forces the cracker to calculate each userís hash separately, which takes a lot more time than if there were a single salt for every user or no salt at all.

note: if you want to crack a hash, you donít want the original password, you want an arbitrary string that matches the hash value (a so-called collision)

View Postcxn, on 10 March 2012 - 03:31 PM, said:

I was wondering if salting at the end of the string is less secure than salting both at the beginnen and the ending of the string.

when youíre concerned about security, salt using the HMAC method (=> hash_hmac()).
Was This Post Helpful? 1
  • +
  • -

#7 cxn  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 33
  • Joined: 10-March 12

Re: Securing password at registration

Posted 10 March 2012 - 09:50 AM

Ok this isn't all too simply for me, bare with me please! (Not I'm not going to bother with securing input boxes in this post)

First I get the password from the registration form:

$password = $_POST["password"];


Next I use hash_hmac with algorythm SHA256 to encode the password string:

$hash = hash_hmac(SHA256,$password,$salt)


where $salt is a randomly generated string of (for example) letters and digits.

final move is to insert $_POST["user"] into my database allong with $hash and $salt.

Am I on the right track? Thanks for the help!
Was This Post Helpful? 0
  • +
  • -

#8 Atli  Icon User is offline

  • Enhance Your Calm
  • member icon

Reputation: 4238
  • View blog
  • Posts: 7,216
  • Joined: 08-June 10

Re: Securing password at registration

Posted 10 March 2012 - 11:11 AM

Yes, that sounds about right.

Note though that the hash_hmac function takes a string as the first parameter. The SHA265 should be quoted.
Was This Post Helpful? 1
  • +
  • -

#9 JackOfAllTrades  Icon User is offline

  • Saucy!
  • member icon

Reputation: 6246
  • View blog
  • Posts: 24,014
  • Joined: 23-August 08

Re: Securing password at registration

Posted 10 March 2012 - 11:22 AM

Quote

PS @ Dormilich: funny, a friend of mine studying computer science recommended MD5!


Well you can now inform your friend otherwise. MD5 was proven to be broken/insufficient by virtue of collisions YEARS ago. Tell him to read this and the Wikipedia entry for more info.
Was This Post Helpful? 0
  • +
  • -

#10 thrca  Icon User is offline

  • D.I.C Head
  • member icon

Reputation: 28
  • View blog
  • Posts: 65
  • Joined: 21-January 12

Re: Securing password at registration

Posted 10 March 2012 - 11:49 AM

View Postcxn, on 10 March 2012 - 09:50 AM, said:

final move is to insert $_POST["user"] into my database allong with $hash and $salt.


Don't forget to sanitize your data, otherwise you will open yourself up to SQL injection attacks.. This is what I use...

Just include it at the top of your page.

sanitizer.php
<?
/*
* File: sanitizer.php
* Author: Jim Barstow
* Copyright: 2012 iShare, LLC
* Date: 03/10/12
* Requirements: PHP 4/5
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details:
* http://www.gnu.org/licenses/gpl.html
*
*/
/*Magic Quotes are EVIL! this runs the sanitize function on the input arrays for the page*/
function sanitize($input) {
  if(is_array($input)) {
    $output=array();
    foreach($input as $k=>$i) {
      $output[$k]=sanitize($i);
    }
  } else {
    if(get_magic_quotes_gpc()) {
      $input=stripslashes(trim($input));
    }
      $output=mysql_real_escape_string(trim($input));
    }
  return $output;
}

$_POST=sanitize($_POST);
$_GET=sanitize($_GET);
$_COOKIE=sanitize($_COOKIE);
$_REQUEST=sanitize($_REQUEST);
?>


Was This Post Helpful? 0
  • +
  • -

#11 cxn  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 33
  • Joined: 10-March 12

Re: Securing password at registration

Posted 10 March 2012 - 12:07 PM

Hi guys! Been working on my registration page again :-) with result I think!

Here's how I made my unique salt. I don't know if it's the most efficient way but it works; basically it generates a string of 8 characters; digits, uppercase and lowercase letters:
	$salt = substr(str_shuffle('0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'), 0, 8);



Next I get my password and apply the hashing (again I have not secured the form data input yet):
	$password = $_POST['password'];
	
	$hash = hash_hmac('SHA256',$password,$salt);


Then I store these data in the database:
mysql_query ("INSERT INTO users (username, salt, hash) VALUES ('$username','$salt','$hash')");


For example: registering with user=Bart and password=Test gave the following (I check it by echoing):

    echo 'Thanks you for registering ' . $username . '<br />';
	echo $salt . '<br />';
	echo $hash;


Thanks you for registering Bart
8hV3BMw9
08a29478811ff492c0613dd56460feceedb70ddf305eadce994ede7b34eb2242



I'm pretty happy about the result, hope I'm doing it right. Next step is to secure my form!
Could anyone give me a little bit of feedback on whether I'm doing this hashing correctly?

Thanks!
Bart


PS:
@Jack I'll most certainly let him know haha!

View Postthrca, on 10 March 2012 - 11:49 AM, said:

Don't forget to sanitize your data, otherwise you will open yourself up to SQL injection attacks.. This is what I use...

Just include it at the top of your page.

sanitizer.php


Hello and thank you for that piece of code. I've read a lot about sanitizing data; however it's a lot different than what you're showing me. Is this all I have to include? Will all my html forms / queries be safe?

I want to be 100% thorough on every step in the coding process :-)
Was This Post Helpful? 0
  • +
  • -

#12 Atli  Icon User is offline

  • Enhance Your Calm
  • member icon

Reputation: 4238
  • View blog
  • Posts: 7,216
  • Joined: 08-June 10

Re: Securing password at registration

Posted 10 March 2012 - 12:09 PM

View Postthrca, on 10 March 2012 - 06:49 PM, said:

This is what I use...

Just include it at the top of your page.

That code assumes three things:

  • That the short.open.tag directive is enabled. (They are disabled by default.) If not, your function would simply be printed into the HTML. Although, it would likely be invisible; ignored as an invalid HTML tag.

  • That he's using the old, soon to be deprecated mysql_* functions to interact with MySQL. More and more people are using PDO and MySQLi these days.

  • That ALL request data is to be put into a MySQL query. - You shouldn't use mysql_real_escape_string on data unless it is going into a MySQL query. Otherwise you may at best be wasting CPU cycles escaping unused values, or at worst corrupting input data meant to be used for other purposes.

Was This Post Helpful? 2
  • +
  • -

#13 Atli  Icon User is offline

  • Enhance Your Calm
  • member icon

Reputation: 4238
  • View blog
  • Posts: 7,216
  • Joined: 08-June 10

Re: Securing password at registration

Posted 10 March 2012 - 12:37 PM

View Postcxn, on 10 March 2012 - 07:07 PM, said:

Could anyone give me a little bit of feedback on whether I'm doing this hashing correctly?

I would suggest is that you make your salt string longer, like 10-16 letters, and that you include special characters. The longer and more unique it is, the better. (Although don't go making 30 char long strings. That's going a bit overboard :))

The method you use to create your salt also has one flaw in it, albeit a minor one. It won't ever use the same character twice. Truly random strings (not that such a thing exists in the computer world) will sometimes use the same character multiple times. You may want to consider creating a function that picks X number of random characters out of a string instead. - But like I say, that's a minor concern. Nothing to get overly concerned about.

View Postcxn, on 10 March 2012 - 07:07 PM, said:

Next I get my password and apply the hashing (again I have not secured the form data input yet):

You don't actually have to secure the password field. As it's going straight into a hash it isn't a threat. - The one thing you may consider doing is validate it. That is, make sure it's within certain parameters. Like minimum length, requiring use of numbers and/or special chars, etc... It's important for security that passwords aren't to short or obvious (dictionary words, dates, names, etc...), as those types of passwords are easier to guess or brute-force.

View Postcxn, on 10 March 2012 - 07:07 PM, said:

Then I store these data in the database:

You may want to consider using PDO or MySQLi (MySQL Improved), instead of the old mysql_* functions. They are very old and don't support things like prepared statements, which is also something you should look into, if you want your code to be secure.
Was This Post Helpful? 0
  • +
  • -

#14 cxn  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 33
  • Joined: 10-March 12

Re: Securing password at registration

Posted 10 March 2012 - 02:24 PM

Quote

I would suggest is that you make your salt string longer, like 10-16 letters, and that you include special characters. The longer and more unique it is, the better. (Although don't go making 30 char long strings. That's going a bit overboard :))

The method you use to create your salt also has one flaw in it, albeit a minor one. It won't ever use the same character twice. Truly random strings (not that such a thing exists in the computer world) will sometimes use the same character multiple times. You may want to consider creating a function that picks X number of random characters out of a string instead. - But like I say, that's a minor concern. Nothing to get overly concerned about.


Now that I'm on it I might as well do it right :-)

I've looked up some random password generators; from now on the salt will be totally randomized from these characters (and it's working excellent):

$lc = 'abcdefghijklmnopqrstuvwxyz'; // lowercase
$uc = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'; // uppercase
$nr = '1234567890'; // numbers
$sp = '^@*+-+%()!?'; //special characters



Quote

You don't actually have to secure the password field. As it's going straight into a hash it isn't a threat. - The one thing you may consider doing is validate it. That is, make sure it's within certain parameters. Like minimum length, requiring use of numbers and/or special chars, etc... It's important for security that passwords aren't to short or obvious (dictionary words, dates, names, etc...), as those types of passwords are easier to guess or brute-force.


Ok I see that the password field is safe since it's going through a sort of 'encryption' first anyway. I guess, however, that I need to secure the username field.

Minimum (and maximum) length sounds easy to me, requiting use of certain numbers and/or special chars.. hmm I guess I have to use reg expressions for this, right? Same if I want to add an e-mail field I guess. (e-mail field needs to be secured as well I guess)



Quote

You may want to consider using PDO or MySQLi (MySQL Improved), instead of the old mysql_* functions. They are very old and don't support things like prepared statements, which is also something you should look into, if you want your code to be secure.


I've heard of PDO but never really used it. You said 'or', does this mean MySQLi is safe enough as well? Or should I definately get the hang of PDO?

My thoughts: Before moving on to a login page I need to understand sessions I guess, I've read a bit about this, I hope it's simple to implement though.

What would you suggest me to do right now?

Thanks again for all the great help!
Was This Post Helpful? 0
  • +
  • -

#15 cxn  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 33
  • Joined: 10-March 12

Re: Securing password at registration

Posted 10 March 2012 - 02:47 PM

----

EDIT:

On Wikihow there's a post on securing form details. In their case they hash the password as well, so I understand that fully now. On the other hand, they use 'mysql_real_escape_string' for $_POST['username'] but later on they use 'htmlspecialchars' on $username when dealing with sessions.

What is this about? Should I be using both as well? Thanks.
Was This Post Helpful? 0
  • +
  • -

  • (2 Pages)
  • +
  • 1
  • 2