حتی گوگل هم رمز حساب گوگل شما رو نمی‌دونه!

حتی گوگل!باور کنید راست میگم! واقعا حتی خود گوگل هم رمز حساب گوگل شما رو نمی‌دونه! ممکنه بپرسید که "پس چجوری موقع لاگین کردن رمز درست رو از اشتباه تشخیص میده؟؟" جوابش رو در یک کلمه می‌شه خلاصه کرد: هش. تو این نوشته می‌خوایم مفهوم هش و یکی از کاربرد های جالب‌اش رو بررسی کنیم.هش (Hash) کردن یعنی چه؟هش کردن یعنی یه داده ای با طول دلخواه رو به یه تابع هش بدیم و اون تابع با انجام یه سری محاسبات ریاضی به ما یه داده‌ی دیگه بده که که بهش میگیم مقدار هش.به این صورت!تابع هش چند تا خاصیت خیلی مهم داره که بدون اون‌ها دیگه نمی‌شه بهش گفت تابع هش:قطعیت: یه تابع هش به ازای یه ورودی خاص، همیشه مقدار ثابتی برمی‌گردونه. یعنی شانس در کار نیست.یک‌طرفه بودن: می‌شه از یه داده به هش‌ اون داده رسید. اما از یه هش نمیشه یه راست به داده اولیه رسید. گفتم یه راست، چون در نهایت میشه به صورت غیر مستقیم چنین کاری رو انجام داد. مثلا اینکه بیایم همه داده هایی که به ذهنمون می‌رسه رو به تابع هش بدیم و خروجی‌هاشونو ذخیره کنیم. بعد توی خروجی‌هایی که داریم دنبال هش دلخواهمون بگردیم و داده متناظرش رو پیدا کنیم. این جوری از هش به داده می‌رسیم؛ ولی همونطور که حدس می‌زنید، اینکار بسیار بسیار سخت و هزینه‌بر و تقریباً غیرممکنه!ثابت بودن طول هش: صرف‌نظر از طول داده، تابع هش همیشه هش با طول ثابت تولید می‌کنه.عدم وجود تصادم (Collision): تصادم یعنی وقتی که یه تابع هش برای دو تا داده مختلف، هش‌های یکسان تولید می‌کنه. در یک تابع هش، پیدا کردن تصادم باید خیلی سخت باشه. نگفتم غیرممکن، چون همیشه می‌شه تصادم پیدا کرد. مثلا اگر طول داده‌ای که به تابع هش می‌دیم از طول هش (که مقدار ثابتی هست) بیشتر باشه، طبیعتا تعداد داده های ممکن از تعداد هش های ممکن بیشتر می‌شه؛ و طبق اصل لانه‌کبوتری، حداقل دو تا داده وجود داره که به یه هش یکسان متناظر شده باشه؛ و این یعنی همون تصادم. پس همیشه تصادم هست؛ اما نکته مهم اینه که پیدا کردن داده هایی که تصادم ایجاد می‌کنن باید سخت باشه. (یه چیز بامزه: گوگل و یه گروه دیگه با همکاری هم دوتا فایل pdf متفاوت ساختن که هش اون‌ها با الگوریتم SHA1 دقیقا یکی می‌شه! از اون به بعد، SHA1 تقریبا منسوخ شد. اطلاعات بیشتر و دانلود اون pdf ها: shattered.io)اینا مهم‌ترین خواص تابع هش بودن؛ اما خواص دیگه‌ای هم وجود دارن که اینجا بهشون اشاره نمی‌کنیم.هش و امنیت رمزعبورهاهش کردن داده‌ها کاربرد های فراوانی داره. از پیدا کردن یه عنصر تو یه آرایه گرفته تا بررسی درستی محتویات فایل‌ها و ارز‌های دیجیتال و... . اما یکی از دم‌دستی ترین کاربرد‌های هش، ذخیره رمزعبور‌ها در یک دیتابیس هست. به این صورت که یک سایت که می‌خواد مشخصات کاربرانش (مثل رمزعبور) رو ذخیره کنه، به جای ذخیره متن رمزعبور، اون رو هش می‌کنه و فقط هش‌ها رو تو دیتابیس ذخیره می‌کنه. اما چرا؟مثلا یک سایت نه چندان خوب رو در نظر بگیرید که رمزعبور کاربرانش رو به همون شکل توی دیتابیس‌اش ذخیره می‌کنه. اگر یک روز، یه هکر به این سایت حمله می‌کنه و بتونه محتویات دیتابیس رو بیرون بکشه، چون رمزها به همون شکل تو دیتابیس ذخیره شده بوده، اون هکر خیلی راحت به همه حساب‌های کاربری اون سایت دسترسی پیدا می‌کنه!حالا یه سایت خوب رو در نظر بگیرید که موقع ذخیره رمزعبورها، به جای خود رمزعبور، هش اون‌ها رو ذخیره می‌کنه. همون هکر‌ها به این سایت هم حمله می‌کنن و دیتابیس‌اش رو هم بیرون می‌کشن. اما چون فقط هش رمزعبورها توی دیتابیس موجوده و همون‌طور که گفتیم، هش‌ها برگشت‌پذیر نیستن، هکرها برای دسترسی به رمزعبورها به مشکل می‌خورن و اون سایت خوب در امان می‌مونه! (البته این فقط یه مثال بود، وگرنه نمی‌شه گفت چنین سایتی حتما در امان می‌مونه...)مثالی از نحوه ذخیره شدن رمز در دیتابیس. خبری از خود رمزها نیست!اما سایت‌هایی که هش ذخیره می‌کنن، چجوری موقع لاگین می‌فهمن که کاربر داره رمز درست رو وارد می‌کنه یا نه؟ جواب این سوال، ساده‌اس! سایت‌ها موقع لاگین، رمزی که کاربر وارد می‌کنه رو هم هش می‌کنن؛ بعد این هش رو با هش موجود توی دیتابیس‌شون مقایسه می‌کنن. چون الگوریتم هش تصادم نداره، در صورت یکی بودن هش‌ها می‌شه به این نتیجه رسید که رمز‌عبور‌ها هم یکیه! و به این صورت درست بودن رمز تشخیص داده می‌شه.همه سایت‌های کوچیک و بزرگی که سرشون به تنشون می‌ارزه (:دی)، اینطوری رمزها رو ذخیره می‌کنن. اما برای سایت‌های بزرگ‌تر و با داده‌های حساس‌تر (مثل گوگل، توییتر، و...)، علاوه بر هش کردن، کار دیگه‌ای هم انجام می‌شه تا امنیت رمزعبورها حتی بیشتر هم بشه. اون‌ها قبل از هش کردن، یه عبارت ثابت و سری رو به متن رمز اضافه می‌کنن و بعد کل متن به دست اومده رو هش می‌کنن. مثلا اگر رمز من باشه apple1234 و اون عبارت سری هم باشه GoLdEnOnIoN، چیزی که تو دیتابیس ذخیره می‌شه هش عبارت "apple1234GoLdEnOnIoN" خواهد بود (البته این عبارت الزاماً به انتهای رمزعبور اضافه نمی‌شه). اینجوری حتی اگر با روش های سخت و زمان‌بر، یه هکر به رمز متناظر با هش برسه، باز به رمز اصلی نمی‌رسه و کارش سخت‌تر هم میشه! به این کار میگن نمک‌زدن (Salting)!اول نمک می‌زنیم، بعد هش می‌کنیم!پس همونطور که دیدید، حتی گوگل هم رمزعبور کاربراشو نمی‌دونه! برای همین هست که وقتی رمز‌عبورتون رو فراموش می‌کنید، به جای رمزتون، یه لینک برای تعویض پسورد یا یه پسورد جدید موقت براتون می‌فرستن؛ نه خود رمز رو! اگر دیدید سایتی احیاناً رمز خودتون رو براتون ایمیل کرد، یعنی به شکل ناایمنی رمز‌ها رو ذخیره می‌کنه و...خلاصهاکثر سایت‌ها رمز عبور کاربراشون رو نمی‌دونن! و این به دلیل نحوه ذخیره رمز عبور‌ها در دیتابیس اون سایت ها هست. رمزها به صورت هش (Hash) شده ذخیره میشن. هش کردن، فرآیندی هست که در اون، یک داده به یک تابع هش داده می‌شه و با انجام محاسبات ریاضی، یک هش محاسبه می‌شه. تابع هش خواصی داره. مثلا اگر یه داده خاص رو به تابع هش بدیم، اون تابع همیشه یک هش یکسان برای اون داده برمی‌گردونه. همچنین طول هش تولید شده توسط یک تابع، همیشه ثابته. یک تابع هش یک‌طرفه هست؛ یعنی با داشتن داده، میشه هش اون رو به دست آورد؛ ولی با داشتن هش، نمی‌شه داده رو به دست آورد (مگر به وسیله راه‌های سخت و هزینه‌بر!). همچنین از دو تا داده مختلف معمولا دو تا هش مختلف به دست میاد؛ مگر در مواردی خاص، که پیدا کردن اون موارد خاص باید خیلی سخت باشه. هش کردن در خیلی جاها کاربرد داره. یکی از کاربرد‌های اون، ذخیره رمزعبور در دیتابیس‌ها هست. اگر به جای متن رمز، رمز رو هش کنیم و فقط هش رو در دیتابیس ذخیره کنیم، در صورت هک شدن دیتابیس، دسترسی به رمزعبورها غیرممکن یا حداقل بسیار سخت می‌شه. همچنین برای بررسی درست بودن رمز موقع لاگین، رمزی که کاربر وارد می‌کنه هش می‌شه و درصورت یکی بودن این هش با هش ذخیره شده در دیتابیس، درستی رمز تایید می‌شه. می‌شه نتیجه گرفت که چون فقط هش در دیتابیس ذخیره می‌شه، صاحب سایت از متن رمز خبر نداره. در سایت‌هایی که اطلاعات حساس‌تر ذخیره می‌شه، علاوه بر هش کردن، متن رمز کمی دستکاری می‌شه (مثلا چیزی بهش اضافه می‌شه) و بعد هش کردن انجام می‌شه. این‌کار، باعث می‌شه تا حتی اگر دیتابیس لو رفت و رمزها از هش‌ها به دست اومد، رمز به دست اومده رمز اصلی نباشه. این روش در اکثر سایت‌ها استفاده می‌شه و یک استاندارد هست.