به نام خدا
سلام دوستان امیدوارم حالتون خوب باشه...
امروز قصد داریم راجع به مقوله رمزنگاری (Cryptography) صحبت کنیم. در واقع در این تاپیک ابتدا اصطلاحات رایج و تاریخچه این حوزه رو مورد بررسی قرار میدیم و بعد به تشریح ساز و کار چند پروتکل رمزنگاری امروزی می پردازیم. در نهایت هم به شرح مکانیزم های رمزنگاری در کانستراکت و PHP خواهیم پرداخت.سلام دوستان امیدوارم حالتون خوب باشه...
رمزنگاری چیست؟
رمزنگاری یا کریپتوگرافی علمی هست که عموماً با تکیه بر اصول ریاضی به انتقال اطلاعات به صورت ایمن (حتی در یک محیط یا کانال نا امن) می پردازه. در واقع در رمزنگاری یک پیام به صورت نامفهومی در میاد تا حتی در صورت لو رفتن پیام در محیط ارتباطی مفهومی استخراج نشه. علاوه بر رمزنگاری اصطلاحی تحت عنوان «استگانوگرافی» یا «پنهان نگاری» هم وجود داره. در مقوله استگانوگرافی همه چیز کاملاً سری هست. به این معنی که حتی اصل وجود یک پیام جهت انتقال هم باید مخفی نگه داشته بشه. پس در استگانوگرافی ما حتی از وجود پیام هم با خبر نیستیم اما در رمزنگاری ما میدونیم که یک پیام در حال انتقال هست اما از مفهوم اون خبر نداریم. به طور مثال در پروسه پنهان نگاری محتوای سری موردنظر در یک فیلم، تصویر و یا صدا توسط فرستنده پنهان میشه که تنها با دونستن مکانیزم پنهان نگاری گیرنده قادر به بازخوانی محتوای پنهان شده است.
چند اصطلاح پایه در دنیای رمزنگاری:
- * متن آشکار (Plain Text): متن آشکار در واقع به پیام موردنظر قبل از انجام پروسه رمزنگاری گفته میشه. متن آشکار همون متن خامی هست که قراره رمزنگاری بشه و کاملاً قابل فهم و درک هست چرا که هنوز هیچ مکانیزم رمزنگاری بر اون اعمال نشده.
- * متن رمز (Cipher): متن رمز یا سایفر متنی هست که بعد از انجام پروسه رمزنگاری بر روی متن آشکار به دست میاد. در واقع یک سایفر خروجی مکانیزم رمزنگاری ما خواهد بود که توسط انسان قابل فهم و درک نخواهد بود.
- * کلید رمز (Key): کلید رمز در واقع مجموعه ای از اعداد یا حروف هست که به کمک اون میشه پروسه رمزنگاری یا رمزگشایی و یا هر دو رو انجام داد. پس با این توضیح یک مکانیزم رمزنگاری علاوه بر متن آشکار ورودی یا ورودی هایی تحت عنوان کلید داره. البته لزوماً همه تکنیک هایی که در دنیای رمزنگاری استفاده میشن با کلید کار نمیکنن که در ادامه راجع بهشون صحبت خواهیم کرد.
الگوریتم ها (روش های) متداول رمزنگاری:
از گذشته تا به امروز روش های رمزنگاری مختلفی توسط اشخاص مختلفی معرفی و عرضه شده. با توجه به گسترده بودن تکنیک های مختلف رمزنگاری اصولاً تکنیک های رمزنگاری رو به چند دسته کلی تبدیل می کنن. این دسته ها عبارتند از:
- * مکانیزم های بدون کلید: همانطور که از نام این دسته از متدها مشخص هست در این روش ها تنها ورودی مکانیزم رمزنگاری متن آشکار خواهد بود. این ویژگی (نداشتن کلید) باعث میشه که برای هر متن آشکار مشخص یک خروجی مشخص داشته باشیم که میتونه مشابه اثر انگشت منحصر به فرد باشه. با تکیه بر همین اصل توابع درهم سازی (Hash) ابداع شدن که جزء تکنیک های رمزنگاری این دسته به شمار میرن. در ادامه مفصلاً راجع به توابع درهم سازی بحث خواهیم کرد.
- * مکانیزم های مبتنی بر کلید: در این مکانیزم ها همونطور که مشخصه در رمزنگاری از کلید استفاده می کنیم. پس با این توضیح خروجی مکانیزم رمزنگاری برای یک متن (پیام) مشخص با کلیدهای متفاوت یکسان و مشابه نخواهد بود.
- * مکانیزم های کلید متقارن (Symmetric): روش ها (مکانیزم های) رمزنگاری کلید متقارن تکنیک هایی بر پایه کلید هستند که در اونها از یک کلید یکسان و مشترک برای رمزنگاری و رمزگشایی اطلاعات استفاده میشه. با این توضیح فرستنده و گیرنده پیام هر دو از یک کلید برای رمزنگاری و رمزگشایی استفاده می کنن. برای مثال مکانیزم های AES و DES جزء تکنیک های رمزنگاری این دسته به حساب میان.
- * مکانیزم های کلید نامتقارن (Asymmetric): مکانیزم های کلید نامتقارن تکنیک هایی بر پایه کلید هستن که در اونها برای هر یک از پروسه های رمزنگاری و یا رمزگشایی از یک کلید به خصوص استفاده میشه. مکانیزم های کلید نامتقارن بر خلاف مکانیزم های کلید متقارن از دو کلید مجزا برای رمزنگاری و رمز گشایی استفاده می کنن که کلید عمومی (Public Key) و کلید خصوصی (Private Key) نامیده میشن. کلید عمومی توسط فرستنده یا فرستندگان و تنها جهت رمزنگاری اطلاعات به خدمت گرفته میشه. پس حفاظت کلید عمومی اهمیت چندانی نداره چرا که امکان رمزگشایی اطلاعات به کمک کلید عمومی میسر نیست. پس میتونیم کلید عمومی رو در دسترس عموم (فرستنده یا فرستنده ها) قرار بدیم. کلید خصوصی دقیقاً بر عکس کلید عمومی تنها در مقوله رمزگشایی اطلاعات کاربرد داره و حفاظت از اون به جهت نقش حساسش اهمیت خاصی داره چرا که هر شخصی با در اختیار داشتن کلید خصوصی قادر به رمزگشایی از اطلاعات رمزنگاری شده هست. بنابراین کلید خصوصی تنها در اختیار گیرندگان (دریافت کنندگان پیام) قرار میگیره چرا که اونها قصد رمزگشایی اطلاعات رو دارند. با توضیحاتی که ارائه شد کاملاً مشخص هست که امنیت مکانیزم های کلید نامتقارن نسبت به مکانیزم های کلید متقارن به دلیل وجود دو کلید مجزا برای رمزنگاری و رمزگشایی بیشتره. اما از نظر سرعت مکانیزم های کلید متقارن سریعتر از مکانیزم های کلید نامتقارن عمل میکنن و طول کلیدی که میسازن هم نسبت به مکانیزم های کلید نامتقارن کوتاه تره.
- * رمز قالبی: در این دسته از مکانیزم ها ابتدا پیام موردنظر به حالت باینری (صفر و یک) تبدیل شده و سپس بیت های به دست آمده به چندین بلوک (Block) تقسیم میشن. در این مکانیزم ها الگوریتم رمزنگاری به جای اینکه بر کل متن اعمال بشه بر هر یک از بلوک ها اعمال میشه و برای رمزنگاری از اطلاعات رمز شده هم پروسه رمزگشایی به صورت بلوک به بلوک انجام خواهد گرفت. در ضمن مکانیزم های قالبی جزء تکنیک های متقارن محسوب میشن.
- * رمزهای جایگزینی: این دسته از روش ها عموماً روش های کلاسیک و قدیمی رمزنگاری را شامل می شود. در این دسته از روش ها حروف الفبا با حروف دیگر بر حسب یک قرارداد (کلید) جایگزین می شدند.
- * رمزهای جایگشتی: این دسته از روش ها که جزء روش های کلاسیک (قدیمی) به حساب میان بر پایه اصلی در ترکیبات ریاضی به نام جایگشت ابداع شده اند. شاید بپرسید که جایگشت دقیقاً چیست؟ به زبان ساده جایگشت مشخص میکنه که اعضای یک مجموعه به چند حالت قابل چینش هستن. برای محاسبه جایگشت اعضای یک مجموعه کافیه مقدار فاکتوریل تعداد اعضای مجموعه رو محاسبه کنیم. به این ترتیب می فهمیم که اعضای مجموعه موردنظر به چند شیوه قابل چینش در کنار یکدیگر هستند. به طور مثال فرض کنید قصد داریم بدانیم سه حرف A و B و C را به چند شیوه می توانیم در کنار هم بچینیم.
![[تصویر: Picture5.png]](http://s12.picofile.com/file/8399599392/Picture5.png)
- در این روش ها بر خلاف رمزهای جایگزینی که حروف تماماً با حرفی غیر از خودشان جایگزین می شوند تنها ترتیب چینش حروف تغییر می کند و اصل حروف تغییری نمی کند.
تاریخچه رمزنگاری (کریپتوگرافی):
رمزنگاری از هزاران سال پیش وجود داشته و حیات خودش رو از اون دوران آغاز کرده. در بسیاری از کتب رمزنگاری از رمز سزار یا رمز افزایشی به عنوان اولین متد (روش) رمزنگاری در تاریخ نامبرده میشه. نقل هست که ژولیوس سزار از این روش رمزنگاری برای ارتباط مخفی از طریق تبادل نامه بین فرماندهان جنگی خودش استفاده میکرده. رمز سزار یک متد رمزنگاری متقارن تلقی میشه و در دسته رمزهای جایگزینی قرار می گیره. مکانیزم این روش بسیار ساده است. در این روش قبل از هر چیز یک جدول تنظیم میشه که در این جدول به هر یک از حروف الفبا یک شماره یا عدد خاص نسبت داده میشه. در این جدول شمارش از عدد صفر شروع میشه. به طور مثال:
![[تصویر: Picture1.png]](http://s12.picofile.com/file/8399592992/Picture1.png)
در جدولی که ترسیم کردیم به هر یک از حروف الفبا از A تا Z یک عدد نسبت دادیم. بعد از تعیین جدول باید نسبت به تعیین کلید یا شیفت (Shift) اقدام کنیم. مقدار شیفت یا کلیدی که تعیین می کنیم با توجه به متقارن بودن تکنیک سزار هم در رمزنگاری و هم در رمزگشایی یکسان خواهد بود با این تفاوت که در پروسه رمزنگاری به میزان شیفت تعیین شده در جدول به سمت جلو پیش روی می کنیم و در پروسه رمزگشایی دقیقاً عکس پروسه رمزنگاری به سمت عقب در جدول حرکت می کنیم. می تونیم دو فرمول ساده ریاضی برای رمزنگاری و رمزگشایی تعیین کنیم.
![[تصویر: Picture2.png]](http://s12.picofile.com/file/8399595426/Picture2.png)
در هر یک از فرمول های بالا عبارت x به معنای شماره حرف موردنظر در جدول تعیین شده، n به معنی مقدار کلید (شیفت) و k نیز به معنی تعداد کل حروف الفبا می باشد که در جدولی که ما قرارداد کردیم برابر با 26 می باشد. همچنین عملگر mod به معنای باقی مانده تقسیم می باشد.
نکته: دقت کنید که برای تعیین میزان کلید (شیفت) الزامی نیست که حتماً اعداد بین یک تا 26 را انتخاب کنیم. بنابراین می توانیم هر عدد دلخواهی را به عنوان کلید اختیار کنیم. بدون شک با بزرگتر شدن مقدار کلید (شیفت) رمزنگاری و رمزگشایی به شیوه شمارش از روی جدول دشوارتر خواهد شد. پس بهتر است در مواقعی که کلید (شیفت) بزرگی داریم از فرمول های ریاضی برای رمزنگاری و رمزگشایی استفاده کنیم.
به طور مثال فرض کنید قصد داریم کلمه BABA رو طبق جدول بالا و با کلید (شیفت) سه رمزنگاری و رمزگشایی کنیم.
در مرحله اول رمزنگاری ابتدا تک تک حروف پیام موردنظر رو استخراج می کنیم. بعد برای هر یک از حروف پیام به میزان سه حرف به جلو در جدول پیش روی می کنیم. بنابراین هر یک از حروف متن آشکار (BABA) به شکل زیر تغییر می کنند:
کد:
B => E
A => D
B => E
A => D
کد:
B => E_3 (1)=(1+3) mod 26=4 => E
A => E_3 (0)=(0+3) mod 26=3 => D
B => E_3 (1)=(1+3) mod 26=4 => E
A => E_3 (0)=(0+3) mod 26=3 => D
کد:
E => B
D => A
E => B
D => A
کد:
E => D_3 (4)=(4−3) mod 26 =1 => B
D => D_3 (3)=(3−3) mod 26=3 => A
E => D_3 (4)=(4−3) mod 26 =1 => B
D => D_3 (3)=(3−3) mod 26=3 => A
یکی دیگه از شیوه های کلاسیک رمزنگاری که جزء مکانیزم های جایگشتی به حساب میاد پلیفیر نام داره. این الگوریتم در جنگ جهانی اول و دوم توسط انگلستان به خدمت گرفته شد. در این شیوه از یک جدول (ماتریس) 5×5 استفاده می کنیم که در واقع حکم کلید رو داره. دقت کنید که تعداد حروف الفبای انگلیسی 26 حرف هست بنابراین جهت انطباق با جدول 5×5 معمولاً حرف Q حذف شده و یا دو حرف I و J را یکسان در نظر می گیریم. ابتدا می بایست تک تک حروف کلید موردنظر را در جدول از بالا و از چپ به راست جای گذاری کنیم و همچنین از نوشتن مجدد حروفی که در جدول یکبار استفاده شده اند پرهیز کنیم. فرض کنید قصد داریم از عبارت playfair exmaple به عنوان کلید استفاده کنیم. بنابراین جدول (ماتریس) 5×5 ما به شکل زیر خواهد شد:
![[تصویر: Playfair_Cipher_building_grid_omitted_letters.png]](https://upload.wikimedia.org/wikipedia/commons/e/ef/Playfair_Cipher_building_grid_omitted_letters.png)
همانطور که گفتیم به دلیل محدودیت جدول 5×5 مجبوریم یک حرف را نماینده یک یا چند حرف تعیین کنیم. به طور مثال در جدولی که ترسیم کردیم سه حرف K و L و M هم ارز یکدیگر هستند.
برای رمزنگاری پیام در مرحله اول باید پیام را به بلوک ها (دسته های) دو تایی تقسیم کنیم. در صورتی که تعداد حروف فرد بود و امکان دسته بندی و ایجاد بلوک های دوتایی میسر نبود یک حرف X هم به پیام اضافه می شود تا امکان ایجاد بلوک های دوتایی میسر شود. بعد از تشکیل بلوک های دوتایی حروف هر یک از بلوک ها را با جدول مطابقت می دهیم و به قوانین زیر در پروسه رمزنگاری توجه می کنیم:
1. در صورتی که حروف بلوک انتخاب شده در جدول شکل یک ستون را تشکیل داد باید حرف بعد هر یک از حروف بلوک موردنظر را در جدول در نظر بگیریم. در صورتی هم که در موقعیت آخرین حرف ستون بودیم باید برای انتخاب حرف رمزنگاری شده آن را از اولین حرف ابتدای ستون انتخاب کنیم و همپنین در صورتی که در موقعیت اولین حرف ستون بودیم دومین حرف ستون را به عنوان حرف رمزنگاری شده انتخاب می کنیم. به طور مثال فرض کنید قصد داریم حروف یک بلوک که شامل B و L هستند رو با جدول زیر و کلید رمز ABCDE تطابق بدیم. دقت کنید که در جدول زیر به دلیل محدودیت جدول 5×5 دو حرف Y و Z را هم ارز در نظر گرفتیم.
![[تصویر: Picture6.png]](http://s12.picofile.com/file/8399603242/Picture6.png)
همانطور که می بینیم دو حرف B و L به صورت ستونی در جدول واقع شده اند و شکل یک ستون رو تشکیل دادن. پس طبق قاعده ای که گفتیم حرف B با حرف بعدی (زیرین) خودش یعنی G جایگزین شده و حرف L هم با حرف بعدی خودش یعنی Q جایگزین خواهد شد.
2. اگر حروف بلوک موردنظر شکل یک ستون را تشکیل ندهند و هر یک از حروف بلوک در یک ستون و ردیف متقاوت قرار بگیرند باید گوشه های مخالف هر حرف را انتخاب کنیم. به طور مثال فرض کنید قصد داریم حروف یک بلوک که شامل M و S هستند رو با جدول زیر و کلید رمز ABCDE تطابق بدیم. دقت کنید که در جدول زیر به دلیل محدودیت جدول 5×5 دو حرف Y و Z را هم ارز در نظر گرفتیم.
![[تصویر: Picture7.png]](http://s13.picofile.com/file/8399603826/Picture7.png)
حالا برای به دست آوردن فرم رمزنگاری شده حرف S گوشه مخالف آن یعنی R را در نظر می گیریم و برای به دست آوردن فرم رمزنگاری شده حرف M نیز گوشه مخالف آن حرف را در نظر می گیریم و فرم رمزنگاری شده را به دست می آوریم. پس بلوک S و M پس از رمزنگاری به شکل R و N خواهد شد.
3. در صورتی که دو حرف تکراری پشت سر هم در پیام داشتیم یک حرف X بین دو حرف تکراری قرار داده و سپس بلوک های دوتایی را تشکیل می دهیم و با جدول تطابق می دهیم.
حالا فرض کنید قصد داریم پیام HIDE رو مشابه جدولی که در ابتدای توضیحات قرارداد کردیم به شیوه پلیفیر رمزنگاری کنیم. بنابراین به طریق زیر عمل می کنیم:
![[تصویر: Picture8.png]](http://s13.picofile.com/file/8399604718/Picture8.png)
پس عبارت رمزنگاری شده برابر با BMOD شد.
برای رمزگشایی عبارات رمزنگاری شده کافی است همانند مقوله رمزنگاری بلوک های دوتایی را تشکیل دهیم. سپس عکس قواعد مطرح شده در پروسه رمزنگاری عمل کنیم. یعنی:
1. در صورتی که حروف انتخاب شده در جدول شکل یک ستون را تشکیل داد باید حرف قبل هر یک از حروف انتخاب شده را در جدول در نظر بگیریم. در صورتی هم که در موقعیت آخرین حرف ستون بودیم باید برای انتخاب فرم رمزگشایی شده آن حرف یکی مانده به آخر را انتخاب کنیم و همچنین در صورتی که در موقعیت اولین حرف ستون قرار داشتیم باید آخرین حرف ستون را به عنوان فرم رمزگشایی شده در نظر بگیریم. به طور مثال فرض کنید قصد داریم حروف یک بلوک از عبارت رمز شده که شامل B و Q هست رو با جدول زیر و کلید رمز ABCDE تطابق بدیم. دقت کنید که در جدول زیر به دلیل محدودیت جدول 5×5 دو حرف Y و Z را هم ارز در نظر گرفتیم.
![[تصویر: Picture9.png]](http://s13.picofile.com/file/8399606692/Picture9.png)
طبق قاعده ای که بیان کردیم چون حرف B در ابتدای ستون واقع شده بود آخرین حرف ستون یعنی V رو در نظر می گیریم. همچنین حرف قبل از Q یعنی L را در نظر می گیریم. پس یعنی بلوک رمزنگاری شده B و Q در حالت اولیه V و L بوده است.
2. اگر حروف بلوک موردنظر شکل یک ستون را تشکیل ندهند و هر یک از حروف بلوک در یک ستون و ردیف متقاوت قرار بگیرند باید گوشه های مخالف هر حرف را انتخاب کنیم. به طور مثال فرض کنید قصد داریم حروف یک بلوک رمزنگاری شده که شامل F و B هستند رو با جدول زیر و کلید رمز ABCDE تطابق بدیم. دقت کنید که در جدول زیر به دلیل محدودیت جدول 5×5 دو حرف Y و Z را هم ارز در نظر گرفتیم.
![[تصویر: Picture10.png]](http://s13.picofile.com/file/8399607276/Picture10.png)
حالا برای به دست آوردن فرم رمزگشایی شده حرف F گوشه مخالف آن یعنی G را در نظر می گیریم و برای به دست آوردن فرم رمزنگاری شده حرف B نیز گوشه مخالف آن حرف را در نظر می گیریم و فرم رمزگشایی شده را به دست می آوریم. پس بلوک F و B پس از رمزگشایی به شکل G و A خواهد شد.
3. در صورتی که پس از رمزگشایی میان دو حرف تکراری در پیام حرف X را مشاهده کردیم اقدام به حذف X های بین حروف تکراری می کنیم تا بتوانیم مفهوم پیام را درک کنیم.
حالا فرض کنید قصد داریم عبارت رمز شده BMOD را طبق جدولی که در ابتدا متصور شدیم رمزگشایی کنیم. پس باید به شکل زیر عمل کنیم:
![[تصویر: Picture11.png]](http://s12.picofile.com/file/8399608542/Picture11.png)
ماشین انیگما (Enigma):
ماشین انیگما در واقع یک صفحه کلید به همراه چند چرخ دنده و چندین لامپ بود که در قرن بیستم برای حفاظت از اطلاعات سری آلمان نازی ابداع شد. در واقع اپراتور دستگاه با تنظیم چرخ دنده ها کلید رمزنگاری را مشخص می کرد و بعد با فشردن هر کلید از روی صفحه کلید بر روی صفحه چراغ یک حرف به غیر از حرف فشرده شده بر صفحه کلید روشن می شد. چالشی که باعث شده بود سیستم انیگما به ظاهر غیر قابل شکست باشد این بود که آلمان های نازی به صورت روزانه تنظیمات چرخ دنده ها را عوض می کردند بنابراین دیگر کشورهای درگیر جنگ با آلمان تنها تا ساعت 12 شب فرصت داشتند که میلیون ها میلیون تنظیمات احتمالی انیگما را بررسی کرده و موفق به رمزگشایی از پیام های نازی ها شوند. اولین تلاش ها برای شکست انیگما توسط ریاضیدانان لهستانی صورت گرفت که منجر به ساخت ماشینی به نام بامب شد که قادر بود پیام های رمزنگاری شده توسط انیگما را با امتحان کردن تنظیمات (کلیدهای) مختلف رمزگشایی کند. اما نازی ها خیلی زود به این مسئله پی بردند و ساز و کار انیگما را پیچیده تر کرده و همچنین به اپراتورها نیز دستور دادند که سه حرف تصادفی قبل از رمزنگاری پیام از روی صفحه کلید انتخاب کنند و سپس به رمزنگاری پیام بپردازند. در همین دوران انگلیسی ها در پروژه سری خود موسوم به اولترا و در بخشی به نام HUT 8 با استخدام آلن تورینگ پدر علم رایانه و هوش مصنوعی و ریاضیدان و چندین شخص دیگر مشغول به آنالیز انیگما و تلاش برای یافتن راهی برای رمزگشایی انیگما بودند. آلن تورینگ و همکارانش موفق شدند از سهل انگاری بعضی اپراتورها (بعضی اپراتورها به جای سه حرف تصادفی سه حرف ثابت و مشخص را وارد می کردند) استفاده کرده و همچنین با توسعه با توسعه ماشین لهستانی بامب پیام های انیگما را رمزگشایی کنند. آنها حتی سیستم آماری برای مشخص کردن اینکه چه مقدار از اطلاعات کشف شده از پیام های رمزنگاری شده باید به دولت و کشورهای متحد برای شکست نازی ها ارائه شود طراحی کردند تا بدون شکاک شدن نازی ها بتوانند تا پایان جنگ جهانی دوم پیام های انیگما را رمزگشایی کنند.
توابع درهم سازی (Hash):
همانطور که در قسمت مربوط به توضیحات انواع مکانیزم های رمزنگاری بیان کردیم توابع هش یا درهم سازی نیازی به کلید ندارند و همین ویژگی باعث میشه که هر ورودی مشخص خروجی مشخصی داشته باشه. پس توابع درهم سازی رو در واقع میتونیم به یک اثر انگشت دیجیتال تشبیه کنیم چرا که هیچ گاه دو مقدار هش برابر نخواهند شد.
همچنین به دلیل عدم استفاده از کلید در توابع هش امکان رمزگشایی اطلاعات وجود ندارد بنابراین می توان گفت که توابع هش در واقع یک پروسه رمزنگاری یک طرفه هستند. البته با تهیه لیست های جامع از خروجی هش عبارت متداول میتونیم اذعان کنیم که امکان دی هش (De-Hash) مقدار هش عبارات متداول وجود داره.
ویژگی برجسته دیگری که در توابع هش حائز اهمیت است یکسان بودن خروجی این توابع از نظر طولی صرف نظر از طول ورودی خواهد بود. به بیان ساده تر تفاوتی نمیکنه که شما یک بیت شعر حافظ یا یک فایل چند گیگابایتی رو هش کنین؛ به هر حال خروجی از نظر طولی یکسان خواهد بود.
این روزها پروسه هش با استفاده از متدهای MD5، SHA-1 و ... انجام میشه.
دقت کنید که حتماً نیازی نیست که شما از هر یک از روش های یاد شده برای هش کردن استفاده کنید. شما میتونید خروجی هش دلخواه خودتون رو طراحی و تنظیم کنین. به طور مثال تعیین کنین که خروجی هش تنها یکسری کاراکتر خاص و یا یک طول خاص باشه.
کاربرد توابع درهم سازی:
توابع در هم سازی (هش) در احراز هویت نقش مهمی رو ایفا میکنن. همچنین در قسمت لاگین وبسایت ها پسوردی که کاربر وارد می کند به صورت یک رشته هش در دیتابیس ذخیره می شود و برای هر بار لاگین به حساب با ورود پسورد توسط کاربر برنامه سمت سرور به صورت آنی پسورد وارده را هش کرده و با مقدار هش ذخیره شده در دیتابیس مقایسه می کند. به طبع زمانی کاربر پسورد درست را وارد کرده است که مقدار دو هش برابر شود.
همچنین توابع درهم سازی (هش) در فشرده سازی داده ها هم به کار میرن.
شرح یک پروتکل رمزنگاری کلید نامتقارن امروزی:
در این بخش قصد داریم یک پروتکل رمزنگاری مشهور امروزه که نامتقارن تلقی میشه و RSA نام داره رو با هم بررسی کنیم.
به طور خلاصه این پروتکل شامل چهار مرحله ساخت کلید، توزیع کلید، رمزنگاری و رمزگشایی میشه. برای شروع رمزنگاری در مرحله اول باید دو عدد اول p و q رو در نظر بگیریم. دقت کنین که برای ایمنی بیشتر در دنیای واقعی این دو عدد بسیار بزرگ در نظر گرفته میشن. در اینجا چون صرفاً جنبه مثال داره دو عدد رو به شکل زیر انتخاب می کنیم:
کد:
p = 61
q = 53
کد:
n = p × q = 61 × 53 = 3233
![[تصویر: Picture12.png]](http://s12.picofile.com/file/8399611868/Picture12.png)
در فرمول بالا p و q دقیقاً مقدار های قرارداد شده در مرحله اول هستند و n هم حاصلضرب p و q است که در مرحله دوم به دست آمد.
برای محاسبه تابع فی اویلر داریم:
کد:
p(3233)=(61−1)×(53−1)=3120
کد:
1 < e < 3120
e = 17
وارون ضربی (Modular Inverse):
وارون ضربی مفهومی در بحث هم نهشتی نظریه اعداد هست. به طور کلی زمانی قادر هستیم وارون ضربی یک عدد رو به پیمانه یک عدد دیگه محاسبه کنیم که ب.م.م (بزرگترین مضرب مشترک) یا GCD اون دو عدد برابر یا یک باشه. بعد از اینکه متوجه شدیم که اصلاً امکان محاسبه وارون ضربی یک عدد به پیمانه عدد دیگری وجود داره باید نسبت به محاسبه وارون ضربی اقدام کنیم. ساده ترین روش برای محاسبه وارون ضربی استفاده از الگوریتم اقلیدسی هست.
برای محاسبه وارون ضربی به روش اقلیدسی باید جدولی شامل ستون های n، b، q، r، t1، t2 و t3 رسم کنیم. هر یک از ستون های این جدول میتونن شامل یک یا چندین ردیف باشن. برای هر ردیف باید از قاعده مخصوص به اون ردیف پیروی کنیم. این قواعد عبارتند از:
![[تصویر: Picture23.png]](http://s12.picofile.com/file/8399623850/Picture23.png)
دقت کنید که در حین کامل کردن جدول بایستی به چند نکته توجه کنیم:
1. در شروع پر کردن جدول مقدار پیمانه ای که قصد داریم در آن وارون ضربی را محاسبه کنیم را n و عدد موردنظر را b در نظر می گیریم.
2. هنگامی پر کردن ستون b را متوقف می کنیم که در حین پر کردن ستون b به عدد یک برسیم. در واقع ظاهر شدن عدد یک در ستون b بیانگر این نکته است که ب.م.م یا GCD دو عدد n و b برابر با یک خواهد بود.
3. هنگامی پر کردن ستون t2 را متوقف می کنیم که تعداد ردیف های ستون t2 برابر با تعداد ردیف های سایر ستون ها شود.
در نهایت بعد از کامل کردن جدول از طریق فرمول زیر وارون ضربی را محاسبه می کنیم.
کد:
t2 mod n
فرض کنین قصد داریم وارون ضربی عدد 11 به پیمانه 26 رو محاسبه کنیم. قبل از هر چیز باید اطمینان حاصل کنیم که قادر به محاسبه وارون ضربی هستیم یا خیر.
کد:
gcd(26,11)=1
برای محاسبه وارون ضربی جدول رو به شکل زیر ترسیم می کنیم:
![[تصویر: Picture17.png]](http://s12.picofile.com/file/8399615734/Picture17.png)
حالا برگردیم سر کار خودمون! گفتیم که باید وارون ضربی عدد e را به پیمانه عدد به دست آمده از تابع فی اویلر محاسبه کنیم. اگر یادتون باشه عدد e برابر با 17 و عدد به دست اومده از تابع فی اویلر برابر با 3120 بود. حالا برای محاسبه وارون ضربی عدد 17 به پیمانه 3120 باید به شکل زیر عمل کنیم:
![[تصویر: Picture19.png]](http://s12.picofile.com/file/8399616542/Picture19.png)
کد:
فرمول رمزنگاری ==> c(m) = c^m mod n
فرمول رمزگشایی ==> m(c) = c^d mod n
(عبارت ^ به معنی عمل توان است)
حالا فرض کنین قصد داریم پیام فرضی 65 رو رمزنگاری و رمزگشایی کنیم. باید بنویسیم:
کد:
c = 65^17 mod 3233 = 2790
(عبارت ^ به معنی عمل توان است)
کد:
m =2790^2753 mod 3233 = 65
(عبارت ^ به معنی عمل توان است)
در حاشیه:
در مکانیزم های رمزنگاری نامتقارن تبادل کلیدها (عمومی و خصوصی) به صورت ایمن در یک محیطی که اطمینانی راجع به ایمنی اون نداریم بسیار حائز اهمیته. برای این منظور پروتکل هایی جهت تبادل کلید مثل پروتکل تبادل کلید دیفی هلمن (برای مطالعه بیشتر راجع به این پروتکل به اینجا مراجعه کنین) ابداع شده اند.
رمزنگاری در PHP:
برای رمزنگاری رشته ها در PHP چند تابع به صورت پیشفرض در این زبان موجود هستن. برای هش کردن از طریق متد MD5 میتونیم از تابع md5() استفاده کنیم و همچنین میتونیم برای هش کردن از تابع crypt() هم استفاده کنیم که هش بر پایه الگوریتم DES و یا Blowfish خواهد بود. برای استفاده از متدهای مختلف هش میتونیم از توابع مختلفی استفاده کنیم که بیان تک تک این توابع از حوصله این مطلب خارجه.
تذکر مهم: برخی افراد تصور می کنن که با یک یا چند بار هش کردن یک رشته امنیت بیشتری رو تأمین می کنن در حالی که از این موضوع غافل هستن که یک یا چند بار هش کردن میتونه احتمال تصادم (یکسان شدن) هش ها رو چندین برابر کنه. پس از این کار به شدت پرهیز کنین.
برای رمزنگاری عادی رشته ها در PHP علاوه بر متدهای مختلف رمزنگاری دیگه که به صورت کلاس و یا کتابخانه در گیت هاب و یا اینترنت موجود هستن میتونیم از متد openssl که در واقع همون روش رمزنگاری متقارن AES هست بهره ببریم.
کد php:
<?php
// Store a string into the variable which
// need to be Encrypted
$simple_string = "Wel";
// Display the original string
echo "Original String: " . $simple_string;
// Store the cipher method
$ciphering = "AES-128-CTR";
// Use OpenSSl Encryption method
$iv_length = openssl_cipher_iv_length($ciphering);
$options = 0;
// Non-NULL Initialization Vector for encryption
$encryption_iv = '1234567891011121';
// Store the encryption key
$encryption_key = "AAxs";
// Use openssl_encrypt() function to encrypt the data
$encryption = openssl_encrypt($simple_string, $ciphering,
$encryption_key, $options, $encryption_iv);
// Display the encrypted string
echo "Encrypted String: " . $encryption . "\n";
// Non-NULL Initialization Vector for decryption
$decryption_iv = '1234567891011121';
// Store the decryption key
$decryption_key = "AAxs";
// Use openssl_decrypt() function to decrypt the data
$decryption=openssl_decrypt ($encryption, $ciphering,
$decryption_key, $options, $decryption_iv);
// Display the decrypted string
echo "Decrypted String: " . $decryption;
?>
حتماً دقت کنین برای انتخاب کلید در این روش از توابع رندوم عادی PHP استفاده نکنین چرا که این توابع از نظر رمزنگاری ایمن تلقی نمیشن. مولدهای کلید های شبه تصادفی جهت رمزنگاری آزمون های ریاضی و آماری متفاوتی رو پشت سر میگذارن تا نسبتاً به مطمئن بودن اونها اطمینان حاصل بشه. برای تولید کلیدهای ایمن در PHP میتونیم از تابع openssl_random_pseudo_bytes() بهره ببریم. کافیه تعداد بیت های کلیدی که قصد داریم PHP برای ما بسازه رو به عنوان تنها پارامتر تابع به شکل زیر وارد کنیم:
کد php:
openssl_random_pseudo_bytes(x);
رمزنگاری در کانستراکت:
در دنیای کانستراکت به صورت پیشفرض اکسپرشن یا اکشنی برای رمزنگاری موجود نیست. برای رمزنگاری در کانستراکت میتونیم از پلاگینی موسوم به CB Hash استفاده کنیم. میتونید این پلاگین رو از اینجا دانلود کنین. همچنین میتونین سورس نمونه این پلاگین رو هم از اینجا دریافت کنین.
به کمک این پلاگین قادر هستین رشته های موردنظرتون با متدهای MD5، SHA-1 و SHA-256 هش کنین. این پلاگین همچنین قادر به دیکد کردن و انکد کردن یک رشته از فرمت بیس 64 (Base64) هم هست.
مطالبی که گفته شد تنها مروری گذرا بر مقوله مهم و حائز اهمیت رمزنگاری بود. این تاپیک میتونه درک خوبی نسبت به دنیای رمزنگاری به شما بده و باعث بشه که به این دنیای جالب علاقه مند بشین.
خوشحال میشم اگر جایی اشتباه یا مبهم ادا شده حتماً در ادامه به بنده گوشزد کنین.
با آرزوی بهترین ها...