User Registration

So I tackled this problem today and this was my solution. I made a register action in my siteController and made a clickable link on my main page. Made the form requesting name, password twice and then email. Here is that code:

<?php $this->pageTitle=Yii::app()->name . ' - Register'; ?>





<h1>Register</h1>





<div class="yiiForm">


<?php echo CHtml::form(); ?>





<?php echo CHtml::errorSummary($form); ?>





<div class="simple">


<?php echo CHtml::activeLabel($form,'username'); ?>


<?php echo CHtml::activeTextField($form,'username') ?>


</div>





<div class="simple">


<?php echo CHtml::activeLabel($form,'password'); ?>


<?php echo CHtml::activePasswordField($form,'password') ?>


</div>





<div class="simple">


<?php echo CHtml::activeLabel($form,'password_repeat'); ?>


<?php echo CHtml::activePasswordField($form,'password_repeat') ?>


</div>





<div class="simple">


<?php echo CHtml::activeLabel($form,'email'); ?>


<?php echo CHtml::activeTextField($form,'email') ?>


</div>





<br/>


<?php echo CHtml::submitButton('Register'); ?>


</div>





</form>


</div>

thats my register.php file.

I made a RegisterForm class:

<?php





class RegisterForm extends CFormModel


{


	public $username;


	public $password;


	public $password_repeat;


	public $email;





	public function rules()


	{


		return array(


			array('username, password, email', 'required'),


			array('password_repeat', 'required', 'on'=>'register'),


			array('password', 'compare', 'on'=>'register'),


			array('username', 'register'),


		);


	}





	public function register()


	{


		if(!$this->hasErrors())  // we only want to authenticate when no input errors


		{


			$username=strtolower($this->username);


			$criteria = new CDbCriteria;


			$criteria->select='username';  // only select the 'username' column


			$criteria->condition='username=:username';


			$criteria->params=array(':username'=>$this->username);


			$user = user::model()->find($criteria);





			// Check if username has already been registered


			if ($user == null)


			{


				$user = new User;


				$user->username = $this->username;


				$user->password = md5($this->password);


				$user->email = $this->email; // needs a validation check


				$user->save();


				$identity=new UserIdentity($this->username,$this->password);


				$identity->authenticate();


				$duration = 3600*24*30;


				Yii::app()->user->login($identity,$duration);


			} else {


				$this->addError('username','Username is already taken');


			}


		}


	}





}

This stops a username being registered twice and also logs the user in after registering. This all works, but I am wondering is this an ok / the right way to do this?

Any comments are welcome!

Seems solid though md5'ing your passwords isn't very safe. Use sha1 and a salt in your hashes.

Quote

How would instead not to use?

hi

dalip :

Quote

Seems solid though md5'ing your passwords isn't very safe. Use sha1 and a salt in your hashes.

would you elaborate on this ?

I thought it was impossible to find out a md5'ed password

I'm not that good in security issues and trying to learn

thank you

Check out this site: http://bokehman.com/cracker/

The gist is that neither md5 or sha1 (without a salt) will provide very strong protection, and that the strength of the password itself gives the most security.

I'd think the length of the salt used in sha1 and it's randomness will increase the time it takes to crack it, maybe to a point that's unrealistic for most script-kiddies.

So for sha1, you can:

Of note, if you try to concatenate the salt and password together in the call to sha1(), you will get a different encryption result, so beware ;)

As far as I know, most sites use one salt that gets referenced by all hashing functions so the comparisons between stored encrypted password and entered encrypted password will match. 

I've seen recommendations to store the salt in the database along with the encrypted password, but that seems a little iffy because if they get the database, they have everything they need, although I'm not sure storing the salt in the code is any better.

Since the salt has to be available somewhere, I suppose the 'ideal' would be to store it on another server so at least if someone cracks in, they'd have to get into multiple machines, which might slow them down…some.

thanks a lot for the answer and the link

I'll do my homework and research

Storing a different salt value for each credential is a good approach. The main advantage of this approach is that it defeats the purpose of rainbow tables. If you database is compromised you may have more serious problems.

Does anyone have a complete example of this approach. I would love to add it to my application

Quote

How would instead not to use?


<?php


public function rules()


   {


      return array(


         array('username', 'unique'),


                        //......other rules);


        }


?>


The unique-Validator requires an AR-model, which is not given in a CFormModel, is it?

unique is to validate against database. CFormModel is not backed by database.

Yay, the best password is a long, complex and unlogical password oO

But if you want salt i saw something like this, an example:

$pass = 'whatevertheuserchoosed';

$salt = 'what'; ( First, or last three or four alphas of the password. )

Or another way:

$salt = md5('password');

With this you dont have to store the salt in the database. While creating “random” salts ;)

Quote

Storing a different salt value for each credential is a good approach. The main advantage of this approach is that it defeats the purpose of rainbow tables. If you database is compromised you may have more serious problems.

So you would generate a random salt when creating user and store in database. Then when authenticating the user you would call upon the salt value to authenticate. Is this right?

I found a pretty good article on hashing here;

http://phpsec.org/ar…rd-hashing.html

Just had a quick look at base SecurityManager…

Could I use this to encrypt/decrypt passwords? And are you able to save the validation key to database?