هش (hash) و انواع آنها در پایتون :: Mr Python | مستر پایتون

هش (hash) و انواع آنها در پایتون

  • ۶۰۱۲

هش (hash) و انواع آنها در پایتون 

درود به همه !

در این پست به مبحث hashing در پایتون میپردازیم  . همینطور که میدونید الگوریتم های hashing کاربرد گسترده ای در مباحث امنیتی دارند و هرروزه در دنیای هک و امنیت آموزش هایی مثل کرک هش MD5 یا ... را میبینیم . امروز میخوایم بررسی کنیم ببینیم اصلا هش چیه و چطوری میشه کرکش کرد . در ابتدا شروع میکنیم مباحث تعریفی راجع به هش ها رو میگیم و سپس میریم ببینیم چه کتابخونه ها و راه هایی برای کار با هش ها در پایتون وجود داره . با ما همراه باشید .

هش (hash) چیست ؟ هر هش ، یک الگوریتم ریاضیاتی است که در ازای دریافت یک داده با طول دلخواه به عنوان ورودی ، داده ای با طول ثابت و منحصر به فرد در خروجی تولید میکند .

طبق تعریف بالا ما میتوانیم داده ای با طول دلخواه به یک ورودی تابع هش بدهیم ولی در هر حالت خروجی با طول ثابت برای ما تولید خواهد کرد . 

همینطور که در تصویر بالا مشاهده میکنید با سه ورودی متفاوت به یک تابع hash ، سه خروجی (digest) متفاوت نیز تولید شده است . دقت کنید در الگوریتم های hashing (بخصوص هش های رمزنگاری) معمولا یک تغییر کوچک در ورودی ، باعث تغییر بزرگی در مقدار خروجی میشود . برای مثال در تصویر بالا مثال دوم و سوم رو ببینید . تنها یک کلمه تغییر کرده ولی خروجی آن ها به طور کامل متفاوت از یکدیگر است . یک کلمه که هیچ ، حتی اگه یک کاراکتر هم تغییر کنه خروجی اصلا یه چیز دیگه میشه !! :) 

 

نکته : در عمل و با توجه به قدرت پردازشی تکنولوژی های امروزی ، نمیتوان متن هش شده را به متن اصلی تبدیل کرد .

طبق نکته بالا شما با استفاده از الگوریتم های hashing فقط میتوانید یک متن را هش کنید ولی به هیچ عنوان نمیتوانید متن هش شده را به حالت اولیه برگردانید . 

 

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

 

چند مورد از معروف ترین الگوریتم های hash : 

 MD5 : الگوریتم MD5 مخفف Message Digest version 5 یکی از معروف ترین الگوریتم های هش است . هش خروجی این الگوریتم 128 بیت طول دارد . مثال : هش عبارت mrpython با استفاده از الگوریتم MD5 ، برابر عبارت 9694e5fcf6b9c3a06a0191dac2193bc3 است . همینطور که میبینید تعداد حروف خروجی ، 32 کاراکتر است . از آنجایی که خروجی در مبنای 16 (HEX) است ، بنابراین هر رقم معادل 4 بیت است . بنابراین 4 * 32 برابر است با طول خروجی که 128 بیت میباشد .

 

SHA-1 : الگوریتم SHA-1 مخفف Secure Hash Algorithm version 1 یکی دیگر از معروف ترین الگوریتم های هش است . خروجی هش این الگوریتم 160 بیت طول دارد . مثال : هش عبارت mrpython با استفاده از الگوریتم SHA-1 برابر عبارت b6a6eae1ec24285de46c26558a90b69b44df8358 است .

 

SHA-2 : الگوریتم SHA-2 مخفف Secure Hash Algorithm version 2 نیز الگوریتم معروف و پر استفاده ای در بین الگوریتم های هش است . این ورژن از الگوریتم SHA ، خود شامل الگوریتم های SHA224 , SHA256 , SHA384 , SHA512 است . هر کدام از این الگوریتم ها خروجی با طول متفاوت دارند . طول خروجی هر الگوریتم رو به روی آن با عدد نوشته شده است. برای مثال SHA224 خروجی 224 بیت دارد ، SHA256 خروجی 256 بیت دارد ، SHA384 خروجی 384 بیت دارد و SHA512 خروجی 512 بیت دارد .

 

در پایتون کتابخانه ای به نام hashlib برای کار با هش ها وجود دارد . 

 

مثال 1 : تولید هش MD5 در پایتون : 

# Example 1 -> MD5 Generator

from hashlib import md5
text = input( "Text : " )
hash_of_text = md5( text.encode() )
print(hash_of_text.hexdigest())

در مثال بالا در ابتدا از کتابخانه ی hashlib ، تابع md5 که کار آن تولید هش md5 است را ایمپورت کردیم . سپس یک متن به عنوان ورودی تابع هش md5 از کاربر گرفته ایم . 

متن داده شده را به شکل encode شده به ورودی تابع md5 داده ایم تا هش آن را برای ما حساب کند . خروجی تابع را در متغییر hash_of_text ذخیره کرده ایم .

سپس تابع hash_of_text.hexdigest را فراخوانی کردیم و خروجی آن را چاپ کردیم . خروجی این تابع ، خروجی هش MD5 در مبنای 16 (hex) است .

 

مثال 2 : تولید هش SHA-1 در پایتون :

# Example 2 -> SHA-1 Generator

from hashlib import sha1
text = input( "Text : " )
hash_of_text = sha1( text.encode() )
print(hash_of_text.hexdigest())


این سورس نیز دقیقا مانند سورس قبل است فقط به جای تابع md5 ، از تابع sha1 برای تولید هش SHA-1 استفاده کردیم . 

 

مثال 3 : تولید هش sha256 در پایتون : 

# Example 3 -> SHA256 Generator

from hashlib import sha256
text = input( "Text : " )
hash_of_text = sha256( text.encode() )
print(hash_of_text.hexdigest())

به همین روال میتوانید از انواع توابع مثل sha256 , sha512 , md5 , sha384 , .... موجود در کتابخانه ی hashlib استفاده کنید .

 

از آنجایی که نمیتوان از متن هش شده به متن اصلی رسید ، هکر ها برای پیدا کردن متن اصلی یک هش از حمله ی Brute Force استفاده میکنند . فرض کنید یک هکر ، هش پسووردی را در اختیار دارد و میخواهد متن اصلی هش که همان پسوورد است را بدست بیاورد . طی این حمله برای کرک هش ، هکر یک دیکشنری یا پسوورد لیست تهیه میکند ، سپس تمام پسوورد های داخل پسوورد لیست را با همان الگوریتمی که هش مورد نظر درست شده هش میکند و با هش مورد نظر مقایسه میکند . هش هرکدام از عبارت های پسوورد لیست با هش مورد نظر یکی شد یعنی پسوورد همان بوده است . 

 

مثال : میخواهیم اسکریپتی بنویسیم که با استفاده از یک پسوورد لیست ، هش b6a6eae1ec24285de46c26558a90b69b44df8358 که هش یک پسوورد است را کرک کند . این هش با استفاده از الگوریتم SHA-1 بدست آمده است .

دقت کنید اگر با هشی مواجه شدیم که نمیدونستیم باچه الگوریتمی درست شده ،  میتونیم یه نگاه به طول آن بیندازیم یا حتی با استفاده از کاراکتر هایی که در آن استفاده شده تشخیص دهیم . همچنین میشه از ابزار های آماده اینکار استفاده کنیم تا وقتمون گرفته نشه . برای مثال سایت زیر به طول آنلاین یک هش از شما میگیرد و الگوریتم آن را حدس میزند :

https://www.tunnelsup.com/hash-analyzer/

 

اسکریپت :

# HASH Cracker

from hashlib import sha1

hash = input("HASH : ")

passlist = open("passlist.txt")

for password in passlist :
    password = password.strip("\n")
    print("testing : {}".format(password))
    hash_of_password = sha1(password.encode()).hexdigest()
    if hash_of_password == hash:
        print("*"*20)
        print("Password : {}".format(password))
        break

 

در ابتدا از کتابخانه ی hashlib تابع sha1 را ایمپورت کرده ایم . از این تابع استفاده میکنیم چون میدانیم هش مورد نظر با این الگوریتم به دست آمده است . سپس یک ورودی به نام hash از کاربر میگیریم که همان هشی است که قرار است کرک کنیم . 

پسوورد لیست مورد نظر را با استفاده از تابع open باز کرده ایم و در متغییر passlist ریختیم . 

یک حلقه ی for روی پسوورد لیست اجرا کرده ایم تا به تمام پسوورد های پسووردلیست دسترسی پیدا کنیم . به ازای هر کدام از پسوورد های پسوورد لیست ، ابتدا n\ آخر آنها را حذف کرده ایم. سپس برای کاربر چاپ کردیم چه پسووردی رو داریم تست میکنیم . بعد از اون هش پسوورد را بدست آوردیم و ریختیم داخل متغییر hash_of_password . حالا این هش رو با هشی که کاربر وارد کرده مقایسه کردیم و گفتیم اگه برابر بود بیا پسوورد رو چاپ کن (وقتی برابر شدن یعنی پسوورد همین بوده ) .

پس از اجرای اسکریپت و دادن ورودی های لازم :

امیدوارم مفید بوده باشه . سوالی بود مطرح کنید .

یا حق !

Telegram Channel : @mrpythonblog

 

ارسال نظر آزاد است، اما اگر قبلا در بیان ثبت نام کرده اید می توانید ابتدا وارد شوید.
شما میتوانید از این تگهای html استفاده کنید:
<b> یا <strong>، <em> یا <i>، <u>، <strike> یا <s>، <sup>، <sub>، <blockquote>، <code>، <pre>، <hr>، <br>، <p>، <a href="" title="">، <span style="">، <div align="">
تجدید کد امنیتی