PDA

View Full Version : هش پسورد در Yii



beh3000
شنبه 26 مهر 1393, 17:40 عصر
سلام دوستان

در yii چطوری میتونم پسوردی که میخوام توی دیتابیس ذخیره کنم رو هش کنم ؟ تنظیمات و نحوه استفادش رو بهم می گید ؟

hooman.pro
شنبه 26 مهر 1393, 22:52 عصر
فقط از cpasswordhelper خود yii استفاده نکن که من کردم مشکل داشت و خود به خود پسورد رو تغییر میداد با چند بار لاگین و یکهو پسورد از بین میرفت!

کامروا
شنبه 26 مهر 1393, 23:18 عصر
مییتونید یک کامپوننت بسازید و تابع هش خودتون رو داخل قرار بدید :


class Tools
{
public static function hash($value)
{
for ($i=0; $i < 1000; $i++)
{
$value = sha1($value . Yii::app()->params['pepper']);
}
return $value;
}
}

desatir7316
یک شنبه 27 مهر 1393, 07:45 صبح
فقط از cpasswordhelper خود yii استفاده نکن که من کردم مشکل داشت و خود به خود پسورد رو تغییر میداد با چند بار لاگین و یکهو پسورد از بین میرفت!
موقع لاگين كه چيزي رو ذخيره نمي كني كه، فقط چك مي كني
پس چطور ممكنه از بين ببره يا تغيير بده
كدتونو دوباره چك كنيد

MMSHFE
چهارشنبه 30 مهر 1393, 08:38 صبح
فقط از cpasswordhelper خود yii استفاده نکن که من کردم مشکل داشت و خود به خود پسورد رو تغییر میداد با چند بار لاگین و یکهو پسورد از بین میرفت!

این کد یک نمونه از مدل Users هست که توی یکی از پروژه هام استفاده کردم:

<?php
/**
* This is the model class for table "{{users}}".
*
* The followings are the available columns in table '{{users}}':
* @property integer $id
* @property string $name
* @property string $username
* @property string $password
* @property integer $confirmed
*/
class Users extends CActiveRecord {
public $captcha;
public $password_repeat;
private $_attributesBackup;
/**
*
* @return string the associated database table name
*/
public function tableName() {
return '{{users}}';
}
/**
*
* @return array validation rules for model attributes.
*/
public function rules() {
// NOTE: you should only define rules for those attributes that
// will receive user inputs.
return array (
array ('name, username, password, confirmed', 'required'),
array ('password_repeat', 'required', 'on'=>'create'),
array ('email', 'email'),
array ('name, username', 'length', 'max' => 255),
array ('password', 'length', 'max' => 40),
array ('username', 'unique', 'on'=>'create', 'caseSensitive' => false),
array ('password', 'compare', 'on'=>'create'),
array ('captcha, password, password_repeat', 'safe'),
// The following rule is used by search().
// @todo Please remove those attributes that should not be searched.
array ('id, name, username, password, confirmed', 'safe', 'on' => 'search'));
}
/**
*
* @return array relational rules.
*/
public function relations() {
// NOTE: you may need to adjust the relation name and the related
// class name for the relations automatically generated below.
return array (
);
}
/**
*
* @return array customized attribute labels (name=>label)
*/
public function attributeLabels() {
return array (
'id' => 'ردیف',
'name' => 'نام و نام خانوادگی',
'username' => 'نام کاربری',
'password' => 'رمز عبور',
'password_repeat' => 'تکرار رمز عبور',
'confirmed' => 'تأیید شده',
);
}
/**
* Retrieves a list of models based on the current search/filter conditions.
* Typical usecase:
* - Initialize the model fields with values from filter form.
* - Execute this method to get CActiveDataProvider instance which will filter
* models according to data in model fields.
* - Pass data provider to CGridView, CListView or any similar widget.
* @return CActiveDataProvider the data provider that can return the models
* based on the search/filter conditions.
*/
public function search() {
// @todo Please modify the following code to remove attributes that should not be searched.
$criteria = new CDbCriteria();
$criteria->compare('id', $this->id);
$criteria->compare('name', $this->name, true);
$criteria->compare('username', $this->username, true);
$criteria->compare('password', self::hashPassword($this->password), true);
$criteria->compare('confirmed', $this->confirmed);
return new CActiveDataProvider($this, array ('criteria' => $criteria));
}
/**
* Returns the static model of the specified AR class.
* Please note that you should have this exact method in all your CActiveRecord descendants!
* @param string $className active record class name.
* @return Users the static model class
*/
public static function model($className = __CLASS__) {
return parent::model($className);
}
/**
* Apply a hash on the password before we store it in the database
*/
protected function afterValidate() {
parent::afterValidate();
if(!$this->hasErrors() && $this->getOriginalAttribute('password') != $this->password) {
$this->password = $this->hashPassword($this->password);
}
}
/**
* Generates the password hash
* @param string $password The password to hash
* @return string The hashed password
*/
public static function hashPassword($password) {
for($i = 0; $i < 1000; $i++) {
$password = sha1(md5($password) . Yii::app()->params['pepper']);
}
return $password;
}
/**
* Checks if the given password is correct
* @param string The password to be validated
* @return boolean Whether the password is valid
*/
public function validatePassword($password) {
return $this->hashPassword($password) === $this->password;
}
/**
* Store original attributes in a backup area
*/
public function afterFind() {
$this->_attributesBackup = $this->attributes;
}
/**
* Get original specific attribute
* @param string $attribute The attribute name to retrieve
* @return mixed The original attribute value
*/
public function getOriginalAttribute($attribute) {
if($this->_attributesBackup && isset($this->_attributesBackup [$attribute])) {
return $this->_attributesBackup [$attribute];
}
return null;
}
}
اگه به درستی از رفتارها توی مدل استفاده کنید، پسورد شما هربار که Update رو صدا بزنید، بطور خودکار عوض نمیشه. اگه جایی از کد ابهامی داره بگین توضیح بدم.

hooman.pro
چهارشنبه 30 مهر 1393, 22:01 عصر
خوب چرا
getOriginalAttribute
این _attributesBackup کجا ست شده؟ شما دارین در واقع چک میکنید که اگر پسورد وارد شد و خواست آبدیت بشه یعنی با پسورد قبلی فرق کرد، قبلش هش بشه؟ درسته؟
من هش کردن رو تو متد beforesave به جای aftervalidate انجام دادم مشکلی داره؟؟

MMSHFE
پنج شنبه 01 آبان 1393, 08:45 صبح
فرق خاصی نداره فقط به شرطی که کاربرد دقیقشون رو بدونید. aftervalidate بعد از اعمال ValidationRuleها اتفاق میفته درحالی که beforesave قبل از ذخیره کردن. ممکنه توی این فاصله خطایی رخ بده و پیغام خطای Yii ظاهر بشه و اگه Attributeهای مدل توی صفحه بیاد، پسورد خام نشون داده میشه و درنتیجه اگه از aftervalidate استفاده کرده باشین، ازنظر امنیتی بهتره.
فیلد attributesBackup_ هم که مشخصه توی کلاس (ابتدا) تعریف شده و توی رویداد afterFind (بعد از پیدا شدن مدل با هرکدوم از متدهای find و findAll و...) مقداردهی میشه. درواقع این روشی که پیاده سازی شده، چک میکنه اگه پسورد مدل با پسورد قبلی (زمان پیدا کردن رکورد) فرق داشت، اونوقت هش کنه نه اینکه هربار ذخیره میکنیم، هش کردن اتفاق بیفته. اینطوری بدون تغییر رمز هم هربار رمز قبلی دوباره هش میشه و درنتیجه کاربر دیگه نمیتونه لاگین کنه. متد getOriginalAttribute هم اسم فیلد رو میگیره و مقدار قبلی اون رو (زمان پیدا شدن مدل) برمیگردونه.

SlowCode
شنبه 03 آبان 1393, 07:47 صبح
به توصیه کارشناسان امنیتی از الگوریتم های sha1 و md5 حتی به صورت مخلوط و الحاق salt استفاده نکنین!
بهتره از الگوریتم BCrypt استفاده کنین.
https://gist.github.com/marcoarment/1053158

MMSHFE
شنبه 03 آبان 1393, 08:13 صبح
الگوریتم رمزنگاری داخلی تابع hashPassword اختیاریه و میشه تغییرش داد. من توی این روش فقط استفاده مناسب از رویدادها و رفتارها در Yii مدنظرم بود. البته توی سیستم خودم از sha1 چندگانه همراه با اضافه کردن Salt و Pepper در هر مرحله استفاده میکنم.

salehforum
شنبه 03 آبان 1393, 23:09 عصر
از هش خود فریم ورک استفاده نمی کنید؟ بسیار امن هست و از بلوفیش 11 هم استفاده میشه
یک هش بسیار طولانی که مقایسش هم خیلی طول میکشه و فقط به صورت برابری دو رشته نیست.
استفادش هم خیلی راحته، خودش تابع چک کردن برابری هم داره

MMSHFE
یک شنبه 04 آبان 1393, 08:57 صبح
همونطور که گفتم انتخاب الگوریتم هش اختیاریه و میشه از الگوریتمهای مختلفی استفاده کرد و من هم تا وقتی ضعف امنیتی در این هش دست ساز خودم (منظورم الگوریتم و منطقشه نه خود سیستم هش sha1) در عمل نبینم، نیازی احساس نمیکنم که یک الگوریتم کندتر رو به کار ببندم. تا حالا که مشکلی با این تابع هش نداشتم ولی قطعاً سیستم هش خود Yii هم خیلی خوب و قدرتمند و انعطاف پذیر طراحی شده.

salehforum
یک شنبه 04 آبان 1393, 18:20 عصر
آقای شهرکی احتمالا همونطور که خودتون هم میدونید این کند بودن عمدی صورت میگیره در الگوریتم های هش تا در مقابل حملات بروت فورس پسورد پیدا نشه!
وگرنه کار سختی بالا بردن سرعت مقایسه در پسورد!
ضمنا این الگوریتم از الگوریتم های غیرقابل بازگشت هست و هر پسوردی رو ده ها بار هش کنید باز هم اعداد مختلفی بدست میاد. جوری نیست که دو تا پسورد برابر یک هش برابر داشته باشن، بررسی کننده ی Yii هست که با الگوریتم های طولانی میفهمه آیا این دو هش بدست اومده مربوط به یک پسورد هستن یا خیر
کندی الگوریتم مقایسه ی هش از مزایای اون هست آقای شهرکی نه معایب اون

MMSHFE
دوشنبه 05 آبان 1393, 08:26 صبح
حرفاتون رو قبول دارم ولی صحبتم اینه که تا الان مشکل خاصی با این سیستم نداشتم که نیاز پیدا بشه سوئیچ کنم و درهرصورت من هم استفاده از خود سیستم رمزنگاری Yii رو پیشنهاد میکنم.

beh3000
دوشنبه 05 آبان 1393, 12:36 عصر
جوری نیست که دو تا پسورد برابر یک هش برابر داشته باشن


اگوریتم خود Yii اینجوریه ؟ ... ایول

میشه نحوه استفاده از الگوریتم خود Yii رو بهم بگید

salehforum
دوشنبه 05 آبان 1393, 19:05 عصر
بله به اینصورته
Yii از کلاس CPasswordHelper بدین منظور استفاده می کنه که استفادش واقعا راحته
رشته ی مدنظرتون رو با کد زیر میتونید هش کنید:

$hash = CPasswordHelper::hashPassword($password);

و بعدا اگه خواستید پسورد وارد شده رو بررسی کنید باید از تابع خود Yii استفاده کنید:

if (CPasswordHelper::verifyPassword($password, $hash))
// password is good
else
// password is bad
Yii از الگوریتم بلوفیش برای هش استفاده می کنه و salt رو هم توسط یه فرمول بدست میاره. بعدا اگر بخواد رشته ی وارد شده رو چک کنه میاد تعدادی زیادی salt توسط فرمول خودش تولید می کنه و تمام اون ها رو با رشته ی داده شده مقایسه می کنه ببینه درست هستند یا نه.