نگاره‌هایی پیرامون امنیت، شبکه و رمزنگاری

31 جولای 2019

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


پاسخ این سوال در تعریف کانال ارتباطی امن نهفته است.
در ادبیات امنیت و رمزنگاری، تعاریف مختلفی از کانال ارتباطی امن وجود دارد. اگر همه‌ی آنچه از ویژگی‌هایی که در این تعابیر مختلف برای امن نامیده‌شدن یک کانال ارتباطی ذکر شده است را گرد هم آوریم، لیست زیر به دست می‌آید:

  • حفظ محرمانگی (Confidentiality): محتوای پیام‌های تبادل شده، برای افراد میانی مسیر قابل استخراج و مشاهده نباشد.
  • حفظ یکپارچگی (Integrity): در صورت تغییر پیام در میان مسیر، دریافت کننده، متوجه این تغییر بشود.
  • حفظ حریم خصوصی (Privacy): با مشاهده‌ی پیام‌های رمزشده‌ی تبادلی، اطلاعات [مهمی] -نظیر رفتار 
    کاربران- قابل استخراج نباشد.
  • حفظ ترتیب و پیش‌گیری از تکرار (Reorder&Replay Attack Prevention): کاربر میانی نتواند با تکرار ارسال یک پیام رمز شده، یا با تغییر ترتیب ارسال بسته‌ها، برداشت اشتباهی از منظور فرستنده‎ی پیام در جهت دریافت کننده‌ی پیام ایجاد کند.

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

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

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

همچنین پدر پونه با زیر نظر گرفتن پیام‌های کانال ارتباطی، می‌تواند تحلیل‌هایی روی رفتار و داده‌های تبادلی بین آن‌ها انجام دهد. مثلا اگه چند بار مشاهده کرد که پونه بعد از دریافت پیام‌رمزشده‌ای که مقدار آن 0x112233445566 است از خانه بیرون می‌رود، می‌تواند تشخیص دهد این پیام قبل از رمز شدن حاوی جمله‌ای شبیه “از خانه بیرون بیا” است و این ناقض Privacy است.

و علاوه بر موارد بالا، اگر پدر پونه، چندین پیام رمزشده‌ی پونه به پرویز را در میان مسیر نگهداری کند و با ترتیب دیگری ارسال کند یا یک پیام رمزشده را به جای یک بار 5 بار ارسال کند، پرویز قادر به تشخیص این موارد نخواهد بود.


افزودن یکپارچگی با Digest یا MAC:

فرض کنید پرویز و پونه، به جای قرارداد ساده‌ی بالا، چنین با هم وعده کنند که هر موقع تصمیم به ارسال پیامی داشته باشند، ابتدا از محتوای پیام یک مقدار Hash تولید کنند و سپس رمز شده‌ی پیام خود را به همراه مقدار Hash (که Digest نیز نامیده می‌شود) ارسال کنند. به عبارت دیگر پیام را به صورت زیر ارسال کنند:

از طرف دیگر، دریافت کننده‌ی پیام هم پس از دریافت پیام، ابتدا قسمت رمز شده را از رمز خارج کند و سپس از مقدار آن، Hash تولید کند و اگر مقدار Hash تولید شده با مقدار Hash دریافتی به همراه پیام رمزشده یکسان بود، به تغییر نکردن پیام در میان مسیر اطمینان کند.

اما چرا؟
جواب: با توجه به این که پدر پونه کلید رمزنگاری X را ندارد، اگر قسمتی از داده‌ی رمز شده در پیام پرویز یا قسمتی از Hash آن یا حتی قسمتی از هر دو بخش آن را تغییر دهد، وقتی پونه بخش رمزشده را از رمز خارج می‌کند و از آن Hash تولید می‌کند، مقدار Hash داده‌ی جدید با مقدار Hash پیوست شده به پیام متفاوت خواهد بود.

بنابراین با این تغییر، علاوه بر Confidentiality، فاکتور Integrity نیز در پیام‌های تبادلی حفظ می‌شود.

مدل بالا ساختار ساده‌ای از پیاده‌سازی Integrity را بیان می‌کند. در پروتکل‌های امروزی، معمولا به جای استفاده از Hashهایی نظیر SHA و MD5، از الگوریتم‌هایی با عنوان الگوریتم‌های MAC یا Message Authentication Code استفاده می‌شود. این الگوریتم‌ها در نهایت همانند Hash یک Digest از پیام اصلی تولید می‌کنند، ولی با این تفاوت که برای تولید این Digest، همانند پروتکل‌های Encryption/Decryption نیاز به یک کلید دارند.


حفظ ترتیب و پیش‌گیری از تکرار با Sequence Number

با مدل توصیف شده در بالا، پدر پونه می‌تواند مانع رسیدن یک پیام به پرویز شود و پرویز از این اتفاق با خبر نمی‌شود. یا برعکس می‌تواند یک پیام پرویز را چندین بار متوالی پشت سر هم به پونه ارسال کند. با توجه به این که پونه قادر به تشخیص این تکرار خراب‌کارانه نیست، این عمل منجر به حمله‌ای به نام Replay Attack می‌شود. برای این که به اهمیت پیش‌گیری از Replay Attack پی ببرید، فرض کنید پدر پونه، بر حسب اتفاق پیام رمزشده‌ای از پرویز را 5 بار به پونه ارسال کند که محتوای آن “عزیزم به پدرت 100 هزارتومان پول بدهکارم، از حسابمان به او بده” است! در ارتباط بین یک کلاینت بانکی با سرور بانکی، چنین پیامی خیلی نامحتمل نیست. بنابراین لازم است به نحوی از این حملات پیشگیری شود.

راه حل ساده‌ای که برای این مسئله وجود دارد، اضافه کردن یک Sequence Number به پیام است. به این صورت که پرویز و پونه قرار می‌گذارند برای هر یک عدد پیامی که به هم دیگر ارسال می‌کنند، در ابتدای هر پیام یک عدد اضافه کنند که این عدد، شماره‌ی تعداد پیام‌هایی است که تا به حال ارسال کرده‌اند و این عدد باید در مکانیزم Hash هم لحاظ شود. از طرف دیگر قرار می‌گذارند اگر یک پیام با Sequence Number تکراری دریافت کردند، از آن پیام چشم‌پوشی کنند. لازم به ذکر نیست که به وسیله‌ی این Sequence Number، پرویز و پونه حتی می‎توانند جابجایی پیام‌ها را تشخیص داده و اصلاح کنند.

حفظ Privacy با …؟

حفظ حریم خصوصی، در سطح‌های مختلف، پیچیدگی‌های مختلفی دارد. یکی از روش‌هایی اولیه‌ای که به ذهن ممکن است برسد این است که برای حفظ حریم خصوصی در حد مشخص نشدن پیام‌های تکراری برای پدر پونه،پرویز و پونه با هم قرار بگذارند هر بار که قصد ارسال پیامی دارند، یک داده‌ی تصادفی تولید کنند و آن داده‌ی تصادفی را به نحوی در ابتدای پیام جای دهند و رمز کنند، که گیرنده پس از دریافت داده‌ی رمزشده و استخراج آن از حالت رمز، بداند از کجا تا به کجای خروجی، آن مقدار تصادفی است و باید حذف شود و از کجا تا به کجای خروجی، پیام اصلی است و باید پاسخ داده شود. به این مقدار تصادفی اصطلاحا Nonce گفته می‌شود. یکی دیگر از روش‌های حفظ حریم خصوصی استفاده از الگوریتم‌هایی است که علاوه بر کلید رمزنگاری به مقداری با عنوان IV یا Initial Vector نیاز دارند. مقدار IV نیز به صورت تصادفی انتخاب می‌شود و بعد به همراه داده‌ی رمزشده ارسال می‌شود. دریافت کننده که کلید رمزنگاری را دارد و مقدار IV را دریافت کرده است، قادر به رمزگشایی پیام است و از آنجا که با هر پیام یک مقدار تصادفی جدید توسط فرستنده برای IV تولید می‌شود، پیام‌های یکسان تکراری، مقدار رمزشده‌ی متفاوت خواهند داشت و پدر پونه به اطلاعاتی دست پیدا نمی‌کند. روش سوم این است که کلید ارتباطی به صورت دوره‌ای و در فواصل کوتاه (مثلا بعد از هر بار گفتگوی پونه و پرویز) تغییر کند و …

در همه‌ی روش‌های بالا (که به خاطر پیچیدگی‌های الگوریتم‌های مختلف رمزنگاری از جزئیات و ملاحظات تکنیکال هر کدام صرف نظر کردیم)، حریم خصوصی تنها تا حدی حفظ می‌شود و بعضی اطلاعات همچنان برای کاربر بیرونی قابل استخراج است. مثلا در همه‌ی روش‌ها، پدر پونه به هر حال به زمان شروع و پایان گفتگوی پرویز و پونه دست پیدا می‌کند. ممکن است این اطلاعات از نظر شما بی اهمیت باشد؛ ولی تصور کنید که یکی از مهم‌ترین حملاتی که در حال حاضر نهادهای امنیتی نظیر NSA روی شبکه‌ی TOR انجام می‌دهند، با هدف کسب همین نوع اطلاعات انجام می‌شود و نتیجه‌ی آن پیگیری و افشای هویت کاربرانی است که سعی در ناشناس ماندن دارند. جزئیات این حملات را اینجا می‌توانید بخوانید؛ ولی به طور خلاصه مهاجم با مشاهده‌ی زمان ورود درخواست کاربران به nodeهای ورودی شبکه و همچنین مشاهده‌ی زمان خروج درخواست‌ها از nodeهای خروجی شبکه، یک Timing Correlation انجام می‌دهد و کاربری را که به یک وب‌سرور خاص دسترسی پیدا می‌کند را پیدا می‌کند. یا به عنوان مثال دیگری، یک نهاد امنیتی قوی می‌تواند علی‌رغم این که قادر به رمزگشایی پیام‌های پیام‌رسانی مانند Signal نیست، با بررسی زمان ارسال ترافیک‌های مربوط به تماس این نرم‌افزار برای کاربران یک شبکه، کاربرانی که با هم مرتبط هستند را شناسایی کند.
البته قابل ذکر است که آنچه در بالا از آن به عنوان حفظ حریم خصوصی یاد کردیم، می‌تواند با عنوان <از بین بردن قابلیت ردیابی> یا همان Traceability افراد و همچنین <حفظ گمنامی> یا Anonymity افراد نیز مطرح شود و شاید این دو واژه عبارت‌های بهتری برای آن باشند. علاوه بر این، کل محتوای این بند می‎تواند به تعبیری زیرمجموعه‎ی محرمانگی قرار داده شود.

روی هم رفته، پیاده سازی پروتکلی که در مقابل این حملات مقاوم باشد به سادگی امکان پذیر نیست و اغلب راه‌هایی که وجود دارد به لحاظ Performance کارایی بالا ندارند. مثلا در مورد شبکه‌ی Tor، یکی از روش‌ها این است که nodeهای میانی، پیام‌هایی را که دریافت می‌کنند، با یک وقفه‌ی تصادفی به node بعدی ارسال کنند. یا روش دیگر این است که همواره بین nodeها، پیام‌هایی در حال تبادل باشد که از دید ناظر بیرونی (مهاجم) قابل تفکیک از پیام‌های اصلی نباشد ولی برای خود nodeهای شبکه، قابل تمییز از پیام‌های واقعی باشند.

دسترس پذیری یا Availability کانال ارتباطی رو فراموش کردیم؟

خیر؛ دسترس پذیری به این معناست که کانال ارتباطی همواره وجود داشته باشد. تامین این ویژگی برای کانال ارتباطی، خیلی از دیدگاه رمزنگاری و امنیتی قابل تامین نیست؛ بلکه روش‌هایی نظیر تامین پهنای باند کافی و تهیه‌ی Replication و پیاده‌سازی مکانیزم‌های High Availability پاسخ‌گوی آن است. به همین دلیل در ابتدای متن اصلی به آن اشاره نکردیم. البته لازم به ذکر است که برای دسترس پذیری کانال ارتباطی موارد دیگری شامل مقاوم بودن سیستم (اعم از خود بستر ارتباطی و نرم‌افزارها و تجهیزات طول مسیر) در برابر حملات DoS و همچنین صحت عملکرد و سرویس‌دهی مداوم همه‌ی تجهیزات و نرم‌افزارها به کاربران احراز هویت شده نیز مورد نیاز است و دسترس‌پذیری محدود به وجود بستر شبکه‌ای کانال ارتباطی نیست.

مسئله‌ی Forward Secrecy

یکی از مسائلی که در ارتباط امن جدیدا مورد توجه قرار گرفته است این است که اگر به نحوی کلیدهای رمزنگاری روی یک رایانه به خطر افتاد و افشا شد، با آن کلیدها، تنها آخرین نشست و آخرین تبادل پیام رمزشده قابل رمزگشایی باشد و مثلا اگر مهاجم ترافیک رمزشده‌ی روزهای قبل را جایی ذخیره و نگهداری کرده است، با کلیدهایی که امروز بدست آورده است نتواند آن‌ها را رمزگشایی کند. ارتباط و الگوریتمی که این ویژگی را دارد، اصطلاحا Forward Secrecy یا همان Perfect Forward Secrecy دارد. این ویژگی، یک ویژگی کانال ارتباطی نیست، بلکه یک ویژگی پروتکل ارتباطی است. به همین دلیل از آوردن آن در لیست ویژگی‌های کانال امن صرف نظر کردیم.

از آنجایی که شایعاتی وجود دارد مبنی بر این که نهادهای جاسوسی/امنیتی نظیر NSA، همه‌ی ترافیک‌های رمزشده‌ی حساس دنیا را Capture و ذخیره می‌کنند تا اگر به نحوی روزی قادر به رمزگشایی آن‌ها بودند (مثلا با بدست آوردن کلیدهای سرورها و کاربران یا با بدست آوردن قدرت شکستن الگوریتم)، اطلاعات درون آن‌ها را از دست ندهند، این ویژگی بیشتر مورد توجه قرار گرفت و در نسخه‌های اخیر TLS به پروتکل اضافه شد. 

پس تبادل کلید امن چی؟

در شرح سوالی که ابتدای این نگاره مطرح کردیم، فرض کردیم پرویز و پونه کلید رمزنگاری را به صورت Face2Face با همدیگر به اشتراک گذاشته اند. این عمل در واقعیت برای ارتباط‌های اینترنتی امکان پذیر نیست و نیازمند فرایندی هستیم که کاربران بتوانند به صورت کاملا امن، کلیدهای رمزنگاری اولیه را (Pre-Shared Key) با هم به اشتراک بگذارند. الگوریتم‌های Key Exchange وظیفه‌ی پیاده‌سازی این فرایند را بر عهده دارند. از آنجایی که این ویژگی نیز همانند ویژگی Forward Secrecy، از ویژگی‌های پروتکل ارتباطی است و به خود کانال ارتباطی امن ارتباطی ندارد، در آینده در ارتباط با نحوه‌ی انجام آن پستی جداگانه خواهیم نوشت.

احراز هویت یا Authentication؟

در ارتباط پرویز و پونه شاید این مسئله خیلی مورد توجه نباشد. اما حالتی را تصور کنید که علاوه بر پرویز و پونه، کاربران دیگری در این شبکه تبادل پیام وجود دارند. با موارد ذکر شده در فوق، اگرچه برای هر کاربر امکان تمییز پیام‌های دیگر کاربران از همدیگر وجود دارد (با این فرض که هر دو کاربر موجود، برای تبادل پیام، یک کلید منحصربفرد محرمانه با یکدیگر به اشتراک گذاشته باشند و فرد دیگری از آن اطلاع نداشته باشد)، اما این تمییز پیام به روش بهینه‌ای قابل انجام نیست. برای حل این مشکل (یعنی برای احراز هویت و تمییز پیام کاربران مختلف از همدیگر)، امضاهای دیجیتالی پا به عرصه‌ی وجود گذاشتند. در پست‌های آتی در ارتباط با این مکانیزم‌ها به صورت مفصل خواهیم نوشت.

صمیمانه شما رو به نظرات مثبت و منفی، که مسلما همه‌ش به بهبود کیفیت این پست و پست‌های آتی کمک می‌کنند، دعوت می‌کنم. هر ایراد فنی/نگارشی و هر مورد از قلم افتاده‌ای رو از طریق نظرات بهم اطلاع بدید اصلاح می‌کنم. دوباره ممنون که [تا به اینجا] خوندید. 🙂

برای خیلی‌ها با عنوان برنامه‌نویس و کارشناس امنیت سامانه‌های مبتنی بر کارت هوشمند یا با عنوان تحلیل‌گر ترافیک و پروتکل‌های شبکه و ارزیاب امنیتی شبکه‌های رایانه‌ای شناخته می‌شم؛ ولی هیچ‌کدام نیستم. حقیقت در مورد من این است که برنامه‌نویسِ علاقمند به مباحث امنیتی هستم که همراه با چایی خیلی بیسکوییت می‌خورد (جیره‌ی کل تیم!)، مصاحبت با آدم‌های جدید و پیدا کردن دوست‌های خوب را خیلی دوست دارد و از به اشتراک گذاشتن دانش، به غایت لذت می‌برد.
دسته‌ها: امنیت شبکه
  • به اشتراک بگذارید:
برچسب‌ها: ، ،
  1. پوریا گفت:

    ممنون
    پست خوبی بود و واضح و شفاف مفاهیم اولیه رو توضیح داده

  2. علی‌اکبر گفت:

    بسی لذت بردیم. بی‌صبرانه منتظر پست‌هایی هستم که مواردی مثل تبادل کلید و امضای دیجیتال را هم توضیح بدید که در متن بهشون اشاره شده‌. خیلی تشکر.

    • ابراهیم قاسمی گفت:

      ممنونم علی‌اکبر جان. خوشحالم مفید بوده. توی پست مربوط به TLS در مورد مواردی که مطرح کردی، صحبت کردم برادر.

  3. علی گفت:

    بسیار عالی بود. خواهش من این است که باز هم از تجارب و دانش خود ما را بهره‌مند نمایید. سپاسگزارم.