آشنایی با تابع و الگوریتم هش (Hash Function) به صورت کامل و ساده

رمزنگاری به معنی دانش تغییر دادن متن پیام یا اطلاعات به کمک کلید رمز و با استفاده از یک الگوریتم رمز است.همیشه برای ذخیره اطلاعات مهم داخل دیتابیس و انتقال اطلاعات مهم از رمز نگاری می‌شود. این کار باعث می‌شود که اگه اطلاعات شما به دست شخص دیگری افتاد و یا موقع انتقال اطلاعات فاش شدند؛هکر یا شخصی که اطلاعات را بدست اورده است نتواند از اطلاعات استفاده کند و کاربردی برای ان نداشته باشد.ما در مقاله ی الگوریتم‌های هش به توضیح رمزنگاری و هش میپردازیم.

اگر شما هم به موضوعات برنامه نویسی علاقه‌مندید و تمایل دارید که این حوزه علم کامپیوتر را یادبگیرید پیشنهاد می‌کنیم در دوره یادگیری برنامه نویسی سون لرن شرکت کنید و از مشاوره رایگان مشاوران ما بهره‌مند شوید.

برقراری امنیت در سایت ها

لزوم استفاده از رمزنگاری و هش (Hash)

در دنیای اینترنت به کرات  پیش اومده  است که سایت‌های بزرگ هک شدن و دیتابیس ان‌ها به دست هکر‌ها افتاده اما چون این سایت‌ها و شرکت‌های بزرگ از الگوریتم‌های رمزنگاری و هش استفاده کرده بودند؛هکر‌ها و دیگر افراد نتوانستند از این دیتابیس‌های مهم و بزرگ  استفاده کنند؛ هرچند در بعضی موارد پیدا کردن الگوریتم هش و رمزنگاری کار ساده ای است و افراد نفوذگر توانایی پیدا کردن اطلاعات مهم را دارند.

جلوگیری از فاش شدن  اطلاعات

برای جلوگیری از پابلیک شدن و قرار اطلاعات مهم سایت شما در لیست فروشندگان دارک وب  راه هایی زیادی وجود دارد به عنوان مثال در داخل  دیتابیس وب سایت باید اطلاعات کاربران به نحوی ذخیره شود که اگر وب سایت  مورد نفوذ قرار گرفت یا سرور مشکل پیدا کرد و دیتابیس در دست افراد نامربوط قرار گرفت؛ مشکلی برای کاربران پیش نیاید و باعث فاش شدن اطلاعات انها نشود.

راه‌های مقابله چیست؟

برای اینکه اطلاعات فاش نشود راه‌های فروانی وجود دارد که در مقاله ی آموزش کامل برقراری امنیت در برنامه نویسی PHP به ان پرداخته ایم اما می‌ توان کار دو  مهم و اساسی انجام داد راه اول هش کردن اطلاعات می‌باشد و راه دوم رمزنگاری اطلاعات . فرق بین هش و رمزنگاری این است که هش هیچ گونه بازگشتی ندارد اما رمزنگاری قابل بازگشت هست. اما راه اول این هست که رمز عبور رو هش کنید و داخل جدول بریزید و موقع ورودی کاربر رمز عبور رو هش و با رمز هش شده داخل جدول مقایسه کنید تنها محدودیت این روش این هست که هش کردن هیچگونه بازگشتی ندارد. salt یا نمک یک مقدار ثابتی هست که به رمز عبور اضافه می‌شود تا رمز گشایی آن را برای هکر سخت کند حال این مقدار میتواند هر چیزی باشد.

هش چیست؟

نمونه یک الگوریتم هش

<?php $password=md5($password);
//use salt
$salt= rand(1,1000);
$password=md5($password.$salt);
?>

در این مثال از یک الگوریتم هش معروف PHP به نام md5 استفاده شده است. این تابع امن نیست اما نه به دلیل اینکه رمز ان  شکسته می‌شود؛ بلکه بخاطر اینکه دیتابیس‌های بسیار بزرگی از این هش در اینترنت وجود دارند و با دادن هش راحت عبارت اصلی بدست می‌آید.منظور از دیتابیس‌های بزرگ در اینترنت این است که افراد مختلف حالت‌های مختلف را درون دیتابیس‌ها ذخیره می‌کنند به عنوان مثال:

 md5('admin')

مقدار خروجی عبارت بالا را درون دیتابیس‌های خود ذخیره کرده اند و با پیدا کردن عبارت شبیه به ان پسورد شما پیدا می‌شود.

حتی با اینکه شما salt به پسورد اضافه کرده باشید باز هم ممکن هست با دیتابیس‌های بزرگی که در سطح اینترنت هست رمز شما فاش شود . اما می‌‌توان برای هش کردن مطمئن از تابع crypt و تابع password_hash استفاده کرد .

توجه : برای استفاده از تابع password_hash نیاز به نسخه PHP 5.5 هست و برای تابع crypt نیاز به PHP 5 می‌باشد .

مثالی از اگوریتم هش password_hash

<?php
//make hash
$hash=password_hash($password, PASSWORD_DEFAULT);
//Diagnosis hash
if(password_verify($inputuser,$hash)){
echo 'Password is valid!';
} else {
echo 'Invalid password.';
}

در مثال بالا ابتدا پسورد کاربر هش می‌شود و بعدا داخل شرط چک می‌شود که کاربر برای لاگین رمز رو درست وارد کرده یا خیر . شما می‌توانید از این تابع در وب سایت خود استفاده کنید .

مثالی از اگوریتم هش crypt

<?php
//make hash
$hashed_password = crypt($password);
//Diagnosis password
if(hash_equals($hashed_password, crypt($password, $hashed_password))){
echo 'password verify';}

در مثال بالا از تابع crypt به صورت تک پارامتری استفاده شده که خود تابع از salt رندوم استفاده میکند . داخل نسخه PHP 5.6 این قابلیت به این تابع اضافه شده که salt را به عنوان پارامتر دوم می‌توان داد .

همه مثال‌‌های بالا هش بود یعنی غیر قابل بازگشت اما می‌توان از تابع رمزنگاری هم استفاده کرد که قابل بازگشت هستند . ساده‌‌ترین تابع برای رمز نگاری تابع base64_encode هست که با تابع base64_decode قابل بازگشت هست . اما برای امنیت بالاتر بنده براتون یک کلاس آماده کردم که می‌توانید از اون برای رمزنگاری امن استفاده کنید و با کلید به عبارت اصلی برسید .

<?php
class encrypt {
               /********* Encode *********/
    public static function encode($pure_string, $encryption_key) {
        $iv_size = mcrypt_get_iv_size(MCRYPT_BLOWFISH, MCRYPT_MODE_ECB);
        $iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
        $encrypted_string = mcrypt_encrypt(MCRYPT_BLOWFISH, md5(base64_encode(trim($encryption_key))), utf8_encode(trim($pure_string)), MCRYPT_MODE_ECB, $iv);
        return base64_encode($encrypted_string);
    }
    /********** Decode ************ */
    public static function decode($encrypted_string, $encryption_key) {
        $iv_size = mcrypt_get_iv_size(MCRYPT_BLOWFISH, MCRYPT_MODE_ECB);
        $iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
        $decrypted_string = mcrypt_decrypt(MCRYPT_BLOWFISH, md5(base64_encode(trim($encryption_key))),base64_decode(trim($encrypted_string)), MCRYPT_MODE_ECB, $iv);
        return $decrypted_string;
    }
}
//how to work?
$hash=encrypt::encode('Mohsen Rajabi', 'a');
//will be printed Mohsen Rajabi 
echo encrypt::decode($hash, 'a')?>

بهترین تابع برای رمزنگاری تابع mcrypt_decrypt هست که از الگوریتم MCRYPT_BLOWFISH در مثال بالا استفاده شده که ار بهترین الگوریتم‌‌های رمزنگاری است . این الگوریتم یک رشته را بر اساس کلیدی که به آن می‌ دهیم رمز و بازیابی میکند .

در هر صورت استفاده از رمزنگاری یا هش به عهده خودتون هست اگر داده‌‌ها نیاز هست که بازیابی شوند از رمزنگاری استفاده کنید و اگر نیاز نیست از هش استفاده کنید .

امیدوارم از این مقاله استفاده کرده باشید .

 
ارسال دیدگاه
ما همه سوالات و دیدگاه ها رو می خونیم و پاسخ میدیم
۱۲ دیدگاه
میلاد ۲۷ فروردین ۱۳۹۹، ۰۱:۲۱
سلام وقت بخیر چجوری میتونم با شما صحبت کنم 09177894840 ممنون میشم وات ساپ یه پیامی بهم بدید .میخواستم راجل مقالتون باهاتون صحبت کنم
عباس ۰۱ مرداد ۱۳۹۸، ۰۷:۵۴
بنظر من بهترین کار استفاده از رمزنگاری اختصصاصی هست. یعنی هر کس برای پروژش یه رمزنگاری اختصصاصی داشته باشه. هم مزایای هش رو داره بدون داشتن کد غیر قابل بازگشته و هم توسط برنامه نویس هرجا خواست کیتونه رمزو بشکونه
محمد جواد ۰۹ اردیبهشت ۱۳۹۸، ۲۰:۰۲
سلام
من مدتی پیش از تابع آماده ای که انتهای این مطلب گذاشتین استفاده کردم . الان میخواستم به php 7.2 مهاجرت کنم . اما این نسخه از mcrypt_get_iv_size پشتیبانی نمیکنه و الان دچار مشکل شدم . پیشنهادتون چیه ؟
Mohammad Javad ۰۵ آذر ۱۳۹۷، ۱۰:۴۱
سلام . معمولا توی بیشتر انجمن ها نوشته شده که امنیت استفاده از هش بهتر از رمز نگاری هستش .
میخواستم سوال کنم کلاسی که خودتون آماده کردید در این حد امنیت داره که برای هش کردم نام کاربری و رمز عبور کاربر در کوکی استفاده بشه ؟
عرفان مومنی ۲۲ شهریور ۱۳۹۷، ۰۳:۵۵
سلام لطفا در زمینه الگوریتم های رمزنگاری مطالب بیشتری منتشر کنید.
Ali.H Norouzi ۲۰ شهریور ۱۳۹۷، ۲۲:۱۷
باعرض سلام خدمت شما دوست عزیز و تشکر بابت این مقاله
سوالی که داشتم این هست که میشه از تابع های هشینگ به صورت تو در تو و زنجیره ای استفاده کرد و در هر لایه یک salt اضاف کرد و آیا تاثیری در ایمن تر شدن دارد یا خیر
مثل :[codeBox]crypt(md5(hash("sha512",$pass).'salt1'),"salt2");[/codeBox]
مرادیان ۲۷ دی ۱۳۹۴، ۲۲:۱۰
احسنت استفاده کردیم
parichehr_es ۱۷ اردیبهشت ۱۳۹۴، ۰۲:۱۱
:cool: مفید وجامع بود.ممنون.
محمد عابدی ۰۹ دی ۱۳۹۳، ۱۷:۳۶
مقاله جالبی بود ! :grin:
محسن رجبی ۰۹ دی ۱۳۹۳، ۲۰:۴۴
ممنون
محمد ۰۹ دی ۱۳۹۳، ۱۷:۰۰
میشه بیشتر توضیح بدید که چطور crypt از random salt استفاده میکنه ؟
محسن رجبی ۰۹ دی ۱۳۹۳، ۲۰:۴۴
خود تابع طوری نوشته شده که اگه salt نذارید خودش یه salt خیلی قوی درست میکنه حالا اینکه چطوری اینکارو میکنه تو خودش هندل شده