آموزش هشینگ (hashing) و محافظت گذرواژه ها -بخش اول
جمعه, ۱۵ بهمن ۱۳۸۹، ۰۸:۵۵ ب.ظ
در زمانهای مختلف سرور ها و دیتابیس ها مورد حمله هکران برای به سرقت بردن اطلاعات قرار گرفته.با این ذهنیت این مهم به نظر میرسد که داده های مهم کاربران نظیر گذرواژه ها قابل بازیابی نباشد.امروز تصمیم دارم نکات اساسی هشینگ و چگونگی محافظت امن از گذرواژه در برنامه های تحت وبتان رو تا حدوی آموزش بدهم.
۱-رفع مسئولیت
علم رمزشناسی به طور کلی یک موضوع کاملا پیچیده ست و من در این مورد خبره نیستم.تحقیقاتی در بسیاری از دانشگاهها و آژانس های امنیتی در این مورد صورت میگیرد.در این مقاله من سعی میکنم تا حد ممکن ساده تر و روانتر صحبت کنم تا به شما روشی مقعول و امن برای ذخیره سازی گذرواژه ها در برنامه های وبتون ارائه بدم.
۲- Hashing چه کاری انجام میدهد؟!
۳-استفاده از یک تابع هش برای ذخیره پسورد
پروسه معمول در هنگام ثبت نام:
۴-مشکل اول:تصادم هش
تصادم هش هنگامی رخ میدهد که دو داده مختلف وارده شده نتیجه هش مشابهی داشته باشد.احتمال این عمل بستگی به تابعی که شما استفاده میکنید دارد.
چگونه میتوان از این عمل سوء استفاده کرد؟!
در یک نمونه،من در اسکریپت های قدیمی که از crc32() برای هش پسوردها استفاده شده بود دیدم.این تابع یک داده ۳۲ بیتی اینتیجر برای نتیجه تولید میکند.این بدان معناست که اینجا فقط ۲*۳۲ خروجی ممکن وجود دارد(مثلا 4,294,967,296).
هش یک پسورد:
و این به شما اجازه خواهد داد تا با موفقیت به اکانت شخص لاگین کنید.
برای نمونه:بعد از اجرای این اسکریپت صحیح برای مدتی رو سیستم،من اینو MTIxMjY5MTAwNg== دریافت کردم.بریم تست کنیم:
در این روزها،یک سیستم خانگی قدرتمند میتونه برای اجرای یک فانکشن هش تقریبا میلیون ها ثانیه وقت صرف کنه.ما به یک تابع هش که رنج بسیار بزرگی داشته باشد نیاز داریم.
برای مثال md5() ممکنه برای تولید هش ۱۲۸ بیت مناسب باشه،این به این صورت ترجمه میشه که می توان 340,282,366,920,938,463,463,374,607,431,768,211,456 خروجی ممکن داشت.این غیر ممکن است که برای یافتن تصادم، تکرارات بسیاری کنیم.به هر حال برخی افراد راههایی برای این کار پیدا کردن(اینو ببنید)
Sha1
Sha1()یک جایگزین مناسب می باشد که همواره مقدارهای هش ۱۶۰ بیتی لانگ تولید میکند.
ادامه دارد...
۱-رفع مسئولیت
علم رمزشناسی به طور کلی یک موضوع کاملا پیچیده ست و من در این مورد خبره نیستم.تحقیقاتی در بسیاری از دانشگاهها و آژانس های امنیتی در این مورد صورت میگیرد.در این مقاله من سعی میکنم تا حد ممکن ساده تر و روانتر صحبت کنم تا به شما روشی مقعول و امن برای ذخیره سازی گذرواژه ها در برنامه های وبتون ارائه بدم.
۲- Hashing چه کاری انجام میدهد؟!
هشینگ بخشی از داده ها را (اعم از کوچک یا بزرگ)به یک قسمت نسبتا کوتاه از داده نظیر یه رشته یا یا اعداد صحیح تبدیل میکند.رایجترین نمونه از توابع هش md5() هست که در بسیاری از زبانها و سیستم ها کاملا محبوب بوده.
$data = "Hello World";با md5() نتیجه اغلب به ۳۲ کارکتر رشته طولانی (long string) تبدیل میشود.اما فقط شامل کارکتر های هگزادسیمال میباشد ، از لحاظ فنی تنها میتواند به ۱۲۸ بیت(۱۶بایت)عدد صحیح بیان کرد.
$hash = md5($data);
echo $hash; // b10a8db164e0754105b7a99be72e3fe5
۳-استفاده از یک تابع هش برای ذخیره پسورد
پروسه معمول در هنگام ثبت نام:
- کاربر فرم ثبت نام را پر میکند،شامل فیلد پسورد.
- وب اسکریپت تمامی اطلاعات را داخل دیتابیس ذخیره میکند.
- در هر حال گذرواژه توسط یک تابع هش قبل ذخیره تغییر پیدا میکند.
- گذرواژه اصلی در هر صورت ذخیره نمیشود،که یک بحث فنی میباشد.
و پروسه لاگین:
- کاربر،نام کاربری(یا ایمیل) و گذرواژه را وارد میکند.
- اسکریپت گذرواژه را از طریق تابع هش مشابه تغییر میدهد.
- اسکریپت رکورد کاربر را از دیتابیس پیدا میکند و پسورد هش شده را میخواند
- هر دوی مقدارها با هم مقایسه شده و در صورت هماهنگی اجازه داده خواهد شد.
۴-مشکل اول:تصادم هش
تصادم هش هنگامی رخ میدهد که دو داده مختلف وارده شده نتیجه هش مشابهی داشته باشد.احتمال این عمل بستگی به تابعی که شما استفاده میکنید دارد.
چگونه میتوان از این عمل سوء استفاده کرد؟!
در یک نمونه،من در اسکریپت های قدیمی که از crc32() برای هش پسوردها استفاده شده بود دیدم.این تابع یک داده ۳۲ بیتی اینتیجر برای نتیجه تولید میکند.این بدان معناست که اینجا فقط ۲*۳۲ خروجی ممکن وجود دارد(مثلا 4,294,967,296).
هش یک پسورد:
echo crc32('supersecretpassword');حال نقش کسی که دیتابیس رو هک کرده روبازی میکنیم و مقدار هش شده رو داریم،ما شاید قادر نباشیم 323322056 رو به supersecretpassword تبدیل کنیم،به هر حال ما میتوانیم شکل دیگری از پسورد که میشود تبدیل کرد را با استفاده از اسکریپت زیر بسازیم.
// outputs: 323322056
set_time_limit(0);این کار ممکن مدتی طول بکشد،هر چند،در نهایت این باید یک رشته را برگرداند،ما میتوانیم از رشته برگردانده شده به جای supersecretpassword استفاده کنیم.
$i = 0;
while (true) {
if (crc32(base64_encode($i)) == 323322056) {
echo base64_encode($i);
exit;
}
$i++;
}
و این به شما اجازه خواهد داد تا با موفقیت به اکانت شخص لاگین کنید.
برای نمونه:بعد از اجرای این اسکریپت صحیح برای مدتی رو سیستم،من اینو MTIxMjY5MTAwNg== دریافت کردم.بریم تست کنیم:
echo crc32('supersecretpassword');چگونه از این کار جلوگیری کنیم؟!
// outputs: 323322056
echo crc32('MTIxMjY5MTAwNg==');
// outputs: 323322056
در این روزها،یک سیستم خانگی قدرتمند میتونه برای اجرای یک فانکشن هش تقریبا میلیون ها ثانیه وقت صرف کنه.ما به یک تابع هش که رنج بسیار بزرگی داشته باشد نیاز داریم.
برای مثال md5() ممکنه برای تولید هش ۱۲۸ بیت مناسب باشه،این به این صورت ترجمه میشه که می توان 340,282,366,920,938,463,463,374,607,431,768,211,456 خروجی ممکن داشت.این غیر ممکن است که برای یافتن تصادم، تکرارات بسیاری کنیم.به هر حال برخی افراد راههایی برای این کار پیدا کردن(اینو ببنید)
Sha1
Sha1()یک جایگزین مناسب می باشد که همواره مقدارهای هش ۱۶۰ بیتی لانگ تولید میکند.
ادامه دارد...
۸۹/۱۱/۱۵
دو نکته:
۱- md5 همیشه یک عبارت ۳۲ کاراکتری (۱۶ بایتی) میده (شما نوشتی «اغلب»)
۲- هدف از استفاده از استاندارد crc (چه crc32 و چه مابقی نسخههای موجود) ایجاد امنیت نیست و هدف معتبرسازی (validation) است.
این رو ببین:
http://en.wikipedia.org/wiki/Cyclic_redundancy_check
A cyclic redundancy check (CRC) or polynomial code checksum is a hash function designed to detect accidental changes to raw computer data, and is commonly used in digital networks and storage devices such as hard disk drives.