رمزنگاری مقدماتی : Password Storage - Salt  - Pepper

رمزنگاری مقدماتی به زبان ساده : Password Storage - Salt - Pepperدر این مطلب میخوایم به نحوه ذخیره سازی پسورد بپردازیم ، وقتی میگیم ذخیره پسورد منظورمون بیشتر هشی هست که سمت Web Application هست و سمت Back-end ذخیره میشه ، و از اونطرف چون اکثر وب اپلیکیشن ها لینوکسی هستن پس یه جورایی ذخیره پسورد توی لینوکس رو هم مورد بررسی قرار دادیم ، ولی جریان برای ویندوز کلا فرق داره که توی سری پیشرفته بررسیش میکنیموقتی شما مکانیزم احرازهویت پسوردی ای پیاده سازی میکنید در جایی ، مثلا سمت وب اپلیکیشن ، مثلا ویندوز مثلا لینوکس یا هرجا ، این پسورد باید یه جا ذخیره بشه ، اگر معمولی ذخیره بشه و هکر ها بهش دسترسی پیدا کنن خیلی بد میشه :) پس میان و اونو هش میکنند و بعد ذخیره میکنن ، اینطوری وقتی مهاجم به هش ها دسترسی پیدا کنه دیگه خیلی راحت نمیتونه پسورد رو استفاده کنهشاید بگید مثلا اگر هکر پسوردو به دست بیاره چه کار میتونه بکنه ؟ اگر یه هکر رو بدست بیاره میتونی بعدا به سیستم راحت تر دسترسی بگیره یا روی ماشین های دیگه دسترسی بگیره و حملات دیگه که توی دسته شبکه قرار میگیرن ، از اون طرف یه قاعده ساده رو ما نباید یادمون بره ، کاربر ها اکثرا یک پسورد رو برای چندین جا استفاده میکنن و اگر یه جا پسوردشون لو بره و شما اون پسورد رو در بقیه جاها استفاده کنید ، میتونید به سایر حساب های مهاجم هم دسترسی بگیریدسر همینه که مقوله ذخیره پسورد خیلی مهمه ، سازوکار و راه همون هشینگه ولی یه تفاوتایی داره که میخوایم بررسی کنیم : فرض کنید یه سایتی داریم و توش 5 تا یوزر ثبت نام کردن ، سایت میاد و پسورد هر یوزر رو به صورت هش ذخیره میکنه ، توی این جدول من به صورت ساده بهتون نمایش میدم که درک کنید بعد میریم کد هاشم نشون میدم:عکس 1وقتی که کاربر ها میخوان وارد شن اول یوزر و بعد پسورد رو تایپ میکنن و سایت هش میگیره از پسوردی که تایپ شده و با هشی که توی دیتابیس بوده مقایسه میکنه ، اگر اوکی بود مجوز ورود رو بهشون میده حالا اگر یه مهاجم بیاد و یه سایتی رو بزنه که هش هاش طبق عکس 1 باشه ، خب میره و به سایت های انلاین میده که کرکش کنن (ما در این مثال از MD5 استفاده کردیم) و راحت پسوردا رو میریزه بیرون :عکس 2همونجور که شاهدید مثل کره کرک شدن و مشکل اینجاست که کاربر مسعود و مجید پسورداشون یکیه ، و این مشکل ایجاد میکنه :) پسورد ها چگونه کرک میشن ؟پسورد های هش شده به این صورت کرک میشن که اول مهاجم میاد یه لیست از پسورد هایی که فکر میکنه کاربرها میسازن رو بدست میاره ، حالا یا حدس میزنه یا با هر حمله ای این لیستو بدست اورده ، بعد این هارو هش میکنه و توی یه جدول ذخیره میکنه به همراه پسورد اصلی ، اون جدول اسمش Lookup Table هست ، و وقتی مهاجم یه هش جدید بدست میاره ، میاد و این هش رو مقایسه میکنه با کل اون Lookup Table و اگر هش نظیرشو پیدا کنه چون پسورد خامشم هست دیگه راحت پسوردو به دست میاره ، و سایتی که بالا ازش استفاده کردیم هم مکانیزم کاریش به همین صورته Pepper چیست ؟ :امدن گفتن خب ، ما بیاییم یه چیز دیگه هم بغل پسورد بزاریم که وقتی هش میگیریم کار رو برای مهاجم سخت تر کنیم و دیگه موقع کرک پسورد ، Lookup Table ها کارساز نباشن ، امدن توی خود کد وب اپلیکیشن یک عبارت ثابت (Pepper) اضافه کردن که وقتی شما ثبت نام میکنید و پسوردتون میخواد برای اولین بار هش بشه ، پسوردتون+اون مقدار ثابت باهم هش میشه (اصطلاحا به نوشتن یک چیز داخل کد برنامه میگن HardCode)عکس 3همونطور که مشاهده میکنید وقتی Pepper ما اضافه شد هش ها عوض شد ، حالا بریم کرکشون کنیم :عکس 4شاهد هستید که Lookup Table ها خیت میشن :) اما کار اینجا تموم نیست ، مشکلی که پابرجاست اینه که اگر مهاجم بتونه سورس کد برنامه رو دربیاره ، به Pepper هم میرسه و میتونه Lookup Table خودشو بسازه ، عههه بد شد که از اونور اگر مهاجم پسورد مسعودو کرک کنه ، پسورد مجیدم کرک کرده :) Salt چیست ؟ : آمدن گفتن ما موقع ثبت نام هرکاربر بیاییم و یه استرینگ یا رشته یا همون عبارت بهش اختصاص بدیم ، به صورت رندوم ، و موقع هش گرفتن با اون هش گرفته بشه :عکس 5و همونطور که شاهدید ما میرسیم به جدول بالا ، وقتی مهاجم به هش ها برسه ، بر فرضی که به کد های وب اپلیکیشن هم دسترسی گرفته باشه ، یه زمان زیادی طول میکشه که بیاد Lookup Table بسازه، یعنی یه لیست پسورد بلـــــــــــــــــند ، و Pepper و Salt بعدش و شروع کنه به ساخت پسورد ! نکته ای که باید تاحالا متوجه میشدید اینه که وقتی Salt پاش به میون امد ، هش پسورد مجید و مسعود عوض شدن ، با وجود اینکه پسورداشون یکی بوده :)الگرتیم های ذخیره پسورد (PBKDF2 - bcrypt - scrypt - Argon2) : نکته آخر در باب ذخیره سازی پسورد بحث الگریتم هشی هست که مورد استفاده واقع میشه ، الگریتم های Hahing ای که تاحالا معرفی کردیم خیلی سریع هستن و اگر با اون ها پسورد رو ذخیره کنیم ، مهاجم موقع کرک خیلی خوشبحالش میشه ?بجاش ما میاییم الگریتمی رو استفاده میکنیم که همونطوری باشه ولی خیلی کُند تر باشه ، که وقتی مهاجم خواست Lookup Table بسازه دهنش آسفالت بشه ?الگریتم های ذخیره سازی پسورد عملیات هشی که مثلا الگریتم MD5 یا SHA2 یکبار یا دوبار انجام میدن رو 1000 بار انجام میده ، و اینطوری باعث میشه حدود دو یا شایدم سه ثانیه فرایند هش کردن طول بکشه ، ولی امنیتی که میده خیلی زیاده ، چرا ؟ فرض کنید مهاجم یک میلیون پسورد داره و میخواد با الگریتم MD5 بیاد و Lookup Table بسازه که ساخت هر پسورد حدودا نیم ثانیه طول میکشه ، چقدر طول میکشه ؟ 140 ساعت حدودا ، حالا اگر با الگرتیم Argon2 اینکارو بکنه چون هر پسورد ساختش 3یا2 ثانیه طول میکشه و به عبارتی 830 ساعت کارش طول میکشه ، یعنی تقریبا 6 برابر بیشتر کارش طول میکشه !!!کد هایی که میزارم رو باهم ببینیم : عکس 6ما میاییم برای مثال توی PHP یه مکانیزم ذخیره سازی پسورد پیاده سازی میکنیم ، خط دوم ما Pepper رو مشخص کردیم و طولشم تو خط سوم معلوم کردیم ، خط 4 و 5 ما Salt مون رو به وسیله توابع درونی خود PHP پیاده سازی کردیموقتی کاربر میخواد وارد شه ، پسوردشو وارد میکنه و ریخته میشه توی متغییر خط 13 ، خود PHP براش یه Salt میسازه تو خط 4و 5 و میریزش تو متغییر خط 15 ، تو خط 7 پسورد کاربر با Pepper و Salt پردازش میشه و توسط الگریتم قدرمتند آرگون 2 رمز میشه و ریخته میشه توی متغییر خط 17 حالا یوزر میخواد لاگین کنه ، وقتی وارد سایت میشه و پسورد رو میزنه توی متغییر خط 19 ریخته میشه و بعد تو خط 21 وارد میشه و وارد تابع شرطی خط 23 میشه ، بعد میره توسط تابع خط 10 پردازش میشه ، توی خط 10 پسورد ورودی کاربر با Salt و Pepper هش میشه و در مقابل پسورد هش شده ذخیره شده از قبل مقایسه میشه ، اگر اوکی بود که احراز میشه ، اگر نبود پیغام Invalid براش میادساختار پسورد ذخیره شده و کار با ابزار Openssl : بزارید با ابزار قدرتمند Openssl یک پسورد بسازیم که ببینید وقتی توی دیتابیس سمت Back-end ذخیره میشه به چه صورت هست :hpn# openssl passwd -1 وقتی ما passwd رو تایپ کردیم یعنی ما قراره بهت یه پسورد بدیم و اونو برامون با الگرتیم 1 که میشه MD5 هش کن ، و از ما پسورد رو میپرسه و به این صورت نشون میده :$1$7bgFW5iI$XmRSlDK3Wd9DkdUiVoEuB0دقت کنید که این استرینگ سه تا علامت دلار "$" داره ، بین دوتای اول عبارت 1 قرار گرفته که میگه الگریتم استفاده شده MD5 عه ، بین علامت دلار دوم و سوم هم مقدار Salt ما قرار گرفته ، چون مشخص نکردیم رندوم زده برامون و از دلار سوم به بعد پسورد هش شده رو گذاشته برامون ، حالا اگر بخوایم Salt رو دستی بزاریم :hpn# openssl passwd -1 -salt Virgool $1$Virgool$macUQAD1nNOHf.yaRZ3gU/ما با سویچ salt- امدیم و مقدار سالت دلخواهمونو وارد کردیم ، این روش اصلا توصیه نمیشه ، چرا؟ چون بالاتر گفتم که Salt باید رندوم باشه ، و اینطوری انگار داریم Pepper میدیم ، از اونطرف اگر دستور رو اینطوری زده باشید خود شل ازتون پسورد رو میگیره که امن تره ، ولی اگر پسورد رو خودتون بهش بدید به این صورت : hpn# echo virgool | openssl passwd -1 -stdin -salt Virgool $1$Virgool$Nie3lsHCp.GEugMtvYDHM0میتونیم با stdin- بهش ورودی بدیم ولی نکته جالبش اینه که این روش اصلا امنیت نداره ، چون اگر مهاجم به شل شما دسترسی بگیره با یه دستور history ساده هم پسورد رو در میاره هم Salt رو :)اگر یه هش بهتون رسید و نفهمیدید چ هشیه میتونید از سایت های زیر استفاده کنید : https://www.tunnelsup.com/hash-analyzer/ https://www.onlinehashcrack.com/hash-identification.php یک مثال عملی و تازه از هک شدن دیتابیس یکی از سایت های ایرانی و عدم استفاده طراحان از Pepper و Salt نتیجه اون :پایگاه‌داده‌ای حاوی بیش از 2 میلیون خط مروبط به قاصدک 24، سامانه خرید اینترنتی بلیط هواپیما قطار اتوبوس و رزرو هتل نشت پیدا کرده ، و شما به هش های این ها نگاه کنید:برای مثال به بالای عکس قاصدک نگاه کنید ، هش خانم فاطمه حسین نژادیان رو تست میکنیم ببینیم پسوردش چیه :راحت تر از اون چیزی که فکر کنید کرک شد :) ، این یک فاجعس و شما فکر نکنید این مطالبی که میخونید چون سادست بدون کاربرده ، اتفاقا رعایت نکردنشون همچین فاجعه هایی به بار میاره !در مطلب بعدی سراغ رمزنگاری میریم و تازه کارمون شروع میشه :) هر سوال یا انتقادی بود در خدمتم ، یاعلی