فرض کنید یک فایل مهم برای ارسال دارید و میخواهید مطمئن شوید که فایل شما به صورت یکپارچه و بدون هیچ تغییری به دست مخاطبتان میرسد. چگونه این کار را انجام میدهید؟ ممکن است بخواهید روشهایی مانند ارسال فایل برای چندینبار یا تماس با مخاطب برای چک کردن فایل و… را انجام دهید؛ اما روش بهتر و مطمئنتری برای این کار وجود دارد و آن هم استفاده از تابع هش میباشد. هش یک تابع ریاضی است. برای درک تابع هش و آشنایی با نحوهی کار آن تا آخر مقاله با ما همراه باشید.
تابع هش چیست؟
تابع هش یک معادله ریاضی است که بسیاری از اشکال رمزگذاری مانند امضای دیجیتال را امکانپذیر میکند و شامل همه چیز اعم از پروتکل HTTPS تا پرداختهای انجام شده در وبسایتها میشود. توابع هش رمزنگاری به طور گسترده در فناوری بلاکچین استفاده میشوند. اصطلاح تابع هش ممکن است کمی ترسناک به نظر برسد، اما درک آن کار بسیار راحتی است؛ تابع هش رمزنگاری فقط یک معادلهی ریاضی است، درست مانند توابعی که در دبیرستان یادگرفتهاید؛ مثل تابع خطی که به شکل y=mX+b نوشته میشود. تابع هش رمزنگاری هم تا حدودی مشابه این موضوع است. در واقع تابع هش یک فرمول با مجموعهای از ویژگیهای خاص است که آن را برای رمزگذاری مفید میکند.
توابع هش یک ورودی دریافت میکنند و یک خروجی با طول ثابت ایجاد میکنند. مقدار خروجی، خلاصهای از دادههای ورودی است. به عنوان مثال، به یک سند کاغذی فکر کنید که مدام آن را مچاله میکنید، تا جایی که دیگر حتی قادر به خواندن محتوای داخل آن نباشید. همچنین میتوان گفت، تقریبا غیرممکن است که مقدار ورودی را بدون دانستن دادههای اصلی، بازیابی کنید. بیایید به یک مثال ساده از تابع هش نگاه کنیم:
این یک مثال بسیار ساده از نحوهی کار تابع هش است و درک کوتاهی از چگونگی کار آن به ما میدهد. همانطور که گفته شد، این یک الگوریتم ریاضی است که دادههای ورودی با اندازه دلخواه را به یک خروجی با اندازه ثابت تبدیل میکند. تابع هش به گونهای طراحی شده است که یک تابع یک طرفه باشد و وارونه کردن آن غیر ممکن باشد. با این حال، در سالهای اخیر چندین الگوریتم هش به خطر افتادهاند. به عنوان مثال، این اتفاق برای MD5 که یک تابع هش شناخته شده است، افتاد و اکنون به راحتی قابل معکوس کردن است. یک تابع هش رمزنگاری ایدهآل باید ویژگیهای زیر را داشته باشد:
- محاسبه مقدار هش باید برای هر نوع داده سریع باشد.
- دستیابی به مقدار ورودی، از مقدار خروجی باید غیرممکن باشد.
- یافتن دو خروجی یکسان حتی به تصادف، باید غیرممکن باشد.
- هر کوچکترین تغییر (حتی یک کاراکتر) در ورودی، باید مقدارخروجی را تغییر دهد.
در ادامه تمامی ویژگیهای یک تابع هش ایدهآل را بطور کامل توضیح دادهایم. همچنین بیان کردهایم، چرا یک تابع هش رمزنگاری قوی، باید این ویژگیها را دارا باشد؟
از تابع هش برای چه کاری استفاده میکنیم؟
توابع هش رمزنگاری به طور گسترده در فناوری اطلاعات استفاده میشوند. ما میتوانیم از آنها برای امضای دیجیتال و انواع احراز هویت استفاده کنیم. همچنین میتوانیم از آنها برای ایندکس کردن دادهها در جداول هش، برای انگشت نگاری، شناسایی فایلها، شناسایی موارد تکراری و همچنین اطلاع از اینکه فایل ارسالی به طور تصادفی یا عمدی دچار آسیب نشده باشد، استفاده کنیم. ما همچنین میتوانیم از آنها برای ذخیرهی رمز عبور استفاده کنیم؛ اما منظور از ذخیرهی رمز عبور چیست؟ اگر وبسایت دارید، به احتمال زیاد نیازی به ذخیره رمز عبور کاربران خود ندارید و شما فقط باید بررسی کنید که آیا رمز عبور کاربر با هر تلاشی که شخص برای ورود میکند، مطابقت دارد یا خیر؟ بنابراین تابع هش باید به خوبی کار کند و محافظت خوبی از کاربران شما را ایجاد کند.
ویژگیهای یک تابع هش قوی
چه چیزی یک تابع هش قوی را ایجاد میکند؟ در حالی که چندین کلاس مختلف از توابع هش رمزنگاری وجود دارد، همه آنها دارای چند ویژگی یکسان هستند. در اینجا چندتا از ویژگیهای یک تابع هش مفید را برای شما بیان کردهایم.
قطعیت (Determinism)
یک تابع هش باید قطعی باشد! منظور از قطعی بودن این است که یک تابع هش باید بدون توجه به اندازهی ورودی که به آن داده میشود، همیشه خروجی را با اندازهی ثابت به شما بدهد. این بدان معنی است که اگر یک جمله را هش میکنید، خروجی حاصل باید به اندازه چیزی باشد که هنگام هش کردن کل کتاب به دست میآورید. مقدار خروجی تابع هش، در یک جمله و در یک کتاب باید برابر باشد. همچنین اگر یک ورودی را ده میلیون بار پشت سر هم وارد کنید، یک تابع هش باید دقیقا همان خروجی را ده میلیون بار تولید کند. بنابراین واضح است که اگر یک تابع هش رمزنگاری با هر بار وارد کردن ورودی، خروجیهای متفاوتی تولید کند، تابع هش تصادفی و در نتیجه غیرایمن خواهد بود.
مقاومت در برابر تصویر اولیه و پردازش نشده (Pre-Image Resistance)
خروجی یک تابع هش باید به گونهای باشد که هیچ اطلاعاتی را در مورد ورودی ندهد، به این ویژگی مقاومت در برابر تصویر میگویند. توجه داشته باشید که الگوریتمهای هش میتوانند هر نوع از ورودی را دریافت کنند و ورودی میتواند از نوع اعداد، حروف، کلمات یا علائم نگارشی باشد؛ یا ممکن است یک کاراکتر تنها باشد، یک جمله از یک کتاب باشد، یک صفحه از کتاب باشد و یا حتی کل کتاب باشد! با این حال صرف نظر از اینکه ورودی چه اندازهای دارد، خروجی تابع هش همیشه یک کد الفبایی با طول ثابت است.
این یک ویژگی مهم به شمار میآید؛ چون اگر هر ورودی طولانی، یک خروجی طولانی تولید میکرد، همین موضوع سرنخ مفیدی برای هکر بود تا بتوانند به راحتی مقدار ورودی را کشف کنند. به عنوان مثال، اگر یک ورودی همیشه خروجی را 1.5 برابر طول خود تولید میکرد، تابع هش اطلاعات ارزشمندی را در اختیار هکرها قرار میداد و هنگامی که هکرها یک خروجی با 36 کاراکتر را میدیدند، بلافاصله متوجه میشدند که ورودی 24 کاراکتر است. بنابراین یک تابع هش زمانی مفید است که هرگونه سرنخ درباره ورودی را پنهان کند. تعیین طول ورودی، نوع کاراکتر ورودی و اینکه ورودی از کاراکترهای تصادفی تشکیل شده است یا رشتهای از کلمات قابل تشخیص، باید غیرممکن باشد.
مقاومت در برابر برخورد (Collision Resistance)
ویژگی مهم دیگری که همهی توابع هش رمزنگاری باید داشته باشند، مقاومت در برابر برخورد است؛ به این معنی که یافتن دو خروجی یکسان، هنگامی که ورودیها متفاوت باشند، عملاً غیر ممکن است. همانطور که گفته شد، ورودیهای یک تابع هش میتواند از هر نوع و با هر اندازهای باشد، بنابراین ورودیهای نامحدودی وجود دارد که میتوان در یک تابع هش وارد کرد. البته همانطور که گفته شد، خروجیها همیشه دارای طول ثابتی هستند.
فرض کنید، تعداد خروجیهایی که یک تابع هش میتواند تولید کند، محدود است. این خبر بدی است و به این معنی است که الگوریتمی که برای هش دادهها استفاده میکنید، خراب و ناامن است؛ نگرانی که در اینجا وجود دارد، این است که ممکن است یک شخصی به عنوان هکر یک فایل مخرب با مقدار هش مصنوعی ایجاد کند که با یک فایل واقعی و ایمن مطابقت داشته باشد و آن را به عنوان خروجی واقعی ارسال کند. بنابراین، یک الگوریتم هش خوب و قابل اعتماد، الگوریتمی است که در برابر ایجاد خروجی یکسان حتی تصادفا، مقاوم باشد.
اثر بهمن یا سقوط ناگهانی (Avalanche Effect)
این بدان معناست که هر تغییری که در یک ورودی ایجاد شود، هر چقدر هم که کوچک باشد، منجر به تغییر بزرگی در خروجی خواهد شد. اساساً، یک تغییر کوچک (مانند افزودن یک کاما) به تغییری بسیار بزرگ تبدیل میشود، از این رو اصطلاح “اثر سقوط ناگهانی” به آن داده شده است.
محاسبات سریع (Computationally Efficient)
یک تابع هش باید از نظر محاسباتی کارآمد باشد و الگوریتمهای هش باید با سرعت معقولی کار کنند. در بسیاری از موقعیتها، الگوریتمهای هش باید مقادیر خروجی را به سرعت محاسبه کنند، این یک ویژگی مهم برای تابع هش رمزنگاری ایدهآل محسوب میشود. البته در نظر داشته باشید که سریعترینها همیشه بهترین نیستند، زیرا سرعت محاسبات باید به نحوهی استفاده از الگوریتم نیز بستگی داشته باشد. برای مثال برای اتصالات وبسایت، شما یک الگوریتم هش سریع میخواهید و گاهی ممکن است، برای هش رمز عبور ایمن نیاز باشد، از الگوریتم کندتر استفاده کنید که اجرای آن زمان بیشتری میبرد.
خروجی غیر قابل معکوس (Impossible To Reverse Engineer)
در نهایت آخرین ویژگی یک تابع هش رمزنگاری مفید این است که برای به دست آوردن ورودی اصلی، هکرها قادر به معکوس کردن فرآیندی که خروجی را ایجاد کرده است، نباشند. به عبارتی تابع هش رمزنگاری ایمن، باید یکطرفه باشد. این ویژگی برای این است که هکرها نتوانند با داشتن خروجی، مقدار ورودی را به دست آورند. البته نمیتوان گفت عمل معکوس کردن غیرممکن است، اما باید به اندازهای سخت باشد که هکر از انجام آن صرف نظر کند و تابع هش، ایمن به شمار بیاید.
تابع هش یکطرفه چیست؟
تابع هش اغلب تابع یک طرفه نامیده میشود؛ زیرا با توجه به ویژگیهای ذکر شده در بالا، یک تابع هش نباید برگشتپذیر باشد. اگر یک هکر بتواند به راحتی یک تابع هش را معکوس کند، کاملاً بیفایده خواهد بود. بنابراین، رمزنگاری به تابع هش یکطرفه نیاز دارد. اجازه دهید، توابع یکطرفه را به بیان سادهتری به شما توضیح دهیم. بهترین راه برای نشان دادن یک تابع هش یکطرفه، تابع مدولار در ریاضی است؛ به بیان سادهتر، توابع مدولار توابع ریاضی هستند که باقیمانده یک مسئله تقسیم را تولید میکنند. برای مثال (10mode3=1)، این یک مسئله صحیح است، چون زمانی که 10 بر 3 تقسیم شود، 1 باقیمانده خواهد داشت؛ بنابراین تنها خروجی و باقیمانده 1 است.
بیاید از معادله (Xmode5=Y) به عنوان تابع خود استفاده کنیم؛ فرض کنید ورودی شما 27 است و خروجی 2 را به شما میدهد. حالا تصور کنید که به همه اعلام میکنید که از تابع هش Xmod5=Y استفاده میکنید و خروجی شما 2 است. آیا کسی میتواند ورودی شما را حدس بزند؟ قطعا نه. به معنای واقعی کلمه تعداد بیشماری ورودی ممکن وجود دارد که میتوان از آنها برای به دست آوردن باقیمانده 2 در این تابع استفاده کرد.
به عنوان مثال، عدد شما ممکن است 7، 52، 3492 یا 23390787 باشد. تا زمانی که شما مقداری را که برای X انتخاب کردهاید، مخفی نگهدارید، تشخیص آن برای هکرها غیرممکن خواهد بود. تابع هش یکطرفه هم دقیقا همینطور است، نمیتوان آن را معکوس کرد و یکطرفه بودن همان چیزی است که یک تابع هش رمزنگاری را بسیار ایمن و مفید میکند.
مثالهایی برای تابع هش
توابع هش به طور گسترده در ارزهای دیجیتال برای ارسال اطلاعات تراکنش به صورت ناشناس استفاده میشوند. به عنوان مثال، بیت کوین، اصلیترین و بزرگترین ارز دیجیتال، از تابع هش رمزنگاری SHA-256 در الگوریتم خود استفاده میکند. به طور مشابه، IOTA که یک پلتفرم برای اینترنت اشیا است، دارای تابع هش رمزنگاری مخصوص خود، به نام Curl است. توابع هش کاربردهای دیگری نیز در دنیای واقعی دارند. برخی از رایجترین استفادهها از توابع هش در ادامه بیان شده است.
تایید رمز عبور
ذخیره کردن رمزهای عبور در یک فایل متنی معمولی خطرناک است، بنابراین تقریباً همه سایتها رمزهای عبور را به صورت هش ذخیره میکنند. هنگامی که کاربر رمز عبور خود را وارد میکند، هش میشود و نتیجه با لیست مقادیر هش شدهی ذخیره شده در سرورها مقایسه میشود. البته این روش هم یک روش ایمن به حساب نمیآید.
تولید و تایید امضا
تأیید امضاها یک فرآیند ریاضی است که برای تأیید صحت پیامها یا اسناد دیجیتال استفاده میشود. یک امضای دیجیتال معتبر، به گیرندهی پیام این اطمینان را میدهد که پیام توسط یک فرستنده آشنا، ارسال شده و همچنین در حین انتقال تغییری نکرده است. یک طرح از امضای دیجیتال، معمولا از سه الگوریتم تشکیل میشود: الگوریتم تولید کلید (key generation)، الگوریتم امضا که با دادن یک پیام و یک کلید خصوصی، امضا تولید میکند (produces a signature) و یک الگوریتم تایید امضا (signature verifying). Merkle Trees که فناوری مورد استفاده در ارزهای دیجیتال است، نوعی امضای دیجیتال محسوب میشود.
بررسی یکپارچه بودن فایل یا پیام
از هشها میتوان برای اطمینان از عدم دستکاری پیامها و فایلها، در حین انتقال استفاده کرد. این عمل یک زنجیرهی اعتماد ایجاد میکند. به عنوان مثال، یک کاربر ممکن است یک نسخهی هش شده از دادههای خود را منتشر کند تا گیرندگان بتوانند مقدار خروجی خود را با مقدار منتشر شده مقایسه کنند و مطمئن شوند که همتراز هستند.
انواع تابع هش محبوب
چندین تابع هش وجود دارد که به طور گسترده مورد استفاده قرار میگیرند و همهی آنها توسط ریاضیدانان و دانشمندان کامپیوتر طراحی شدهاند. البته در طول تحقیقات بیشتر، بعضی از آنها نقاط ضعف نشان دادهاند، اما همچنان برخی از این توابع هش از محبوبیت زیادی برخوردار هستند. ما در ادامهی این مقاله به تجزیه و تحلیل و مقایسهی توابع هش محبوب میپردازیم.
Message Digest (MD)
قبل از هر چیزی باید بگوییم که MD5 برای چندین سال محبوبترین و پرکاربردترین تابع هش بود، اما اکنون کاملا منقرض شده است! MD5 یکی از اولین الگوریتمهایی است که مورد تایید گسترده قرار گرفته بود. MD5 در سال 1991 طراحی شد و در آن زمان به طور قابل توجهی ایمن در نظر گرفته میشد، اما با گذشت زمان هکرها نحوه رمزگشایی این الگوریتم را کشف کردند و اکنون میتوانند در عرض چند ثانیه این الگوریتم را رمزگشایی کنند.
اکثر متخصصان عقیده دارند، MD5 برای استفاده گسترده ایمن نیست، زیرا شکستن آن بسیار آسان شده است؛ اما هنوز هم در تقسیمبندی پایگاه داده و تأیید اعتبار فایلهای ارسالی، استفاده میشود. اگر با یک زبان برنامهنویسی آشنا شده باشید، قطعا این الگوریتم را میشناسید. خانواده MD از توابع هش MD2، MD4، MD5 و MD6 تشکیل شده است و یک تابع هش 128 بیتی است.
SHA-1
SHA مخفف عبارت Secure Hash Algorithm است. اولین نسخه الگوریتم SHA-1 بود و بعداً SHA-2 جای آن را گرفت. در حالی که MD5 یک هش 128 بیتی تولید میکند، SHA1 هش 160 بیتی (20 بایت) تولید میکند و یک عدد صحیح 40 رقمی در قالب هگزادسیمال، است. این تابع هش نیز همانند MD5، برای برنامههای رمزنگاری طراحی شده بود، اما به سرعت مشخص شد که آسیبپذیر میباشد.
SHA-2
نسخه دوم SHA، که SHA-2 نام دارد، دارای انواع مختلفی است. رایجترین مورد در الگوریتم SHA-256 است که مؤسسه ملی استاندارد و فناوری (NIST) استفاده از آن را به جای MD5 یا SHA-1 توصیه میکند. الگوریتم SHA-256 مقدار هش 256 بیتی یا 64 رقم هگزادسیمال را برمیگرداند. در حالی که این الگوریتم هنوز کامل نیست، با این حال تحقیقات فعلی نشان میدهند که این الگوریتم به طور قابل توجهی از MD5 یا SHA-1 ایمنتر است. الگوریتم SHA-256 در هک شدن، حدود 20 تا 30 درصد کندتر از هش MD5 یا SHA-1 میباشد، بنابراین ایمنتر است.
RIPEMD
RIPEMD مخفف عبارت RACE Integrity Primitives Evaluation Message Digest است. این مجموعهای از توابع هش است که به طور کلی به عنوان خانوادهای از توابع هش اروپایی شناخته میشود. این مجموعه شامل RIPEMD، RIPEMD-128 و RIPEMD-160 میباشد. همچنین نسخههای 256 و 320 بیتی این الگوریتم نیز وجود دارد. RIPEMD اصلی (128 بیت) بر اساس اصول طراحی استفاده شده در MD4 طراحی شده است. RIPEMD-160 نسخه بهبود یافته و پرکاربردترین نسخه در خانواده است. نسخه های 256 و 320 بیتی احتمال برخورد تصادفی را کاهش میدهند، اما در مقایسه با RIPEMD-128 و RIPEMD-160 از سطوح امنیتی بالاتری برخوردار نیستند.
Whirlpool
الگوریتم Whirlpool یکی از توابع هش رمزنگاری است که در سال 2000، طراحان این الگوریتم را بر اساس استاندارد رمزگذاری پیشرفته ایجاد کردند و بسیار امن در نظر گرفته میشود. تا به حال سه نسخه از الگوریتم Whirlpool منتشر شده است:
- WHIRLPOOL-0
- WHIRLPOOL-T
- WHIRLPOOL
به نظر شما توابع هش چقدر در حفظ امنیت زندگیهای ما تاثیرگذار بودهاند؟ دیدگاهها و تجربیات ارزشمند خود را با ما و سایر کاربران همیار آیتی بهاشتراک بگذارید.