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

رمزنگاری مقدماتی به زبان ساده : رمزنگاری متقارن یا کلید خصوصی یا Symmetric Encryption
رمزنگاری مقدماتی به زبان ساده : رمزنگاری متقارن یا کلید خصوصی یا Symmetric Encryption

در این مطلب میریم سراغ بحث رمزنگاری و معرفی انواعش و رمز نگاری متقارن ، اگر از مقاله اول یادتون باشه هدف اول ما از رمزنگاری بحث Confidentiality یا محرمانگی بود و اینجا با Encryption بهش میرسیم

رمزنگاری چیست ؟

عکس 1
عکس 1

وقتی شما یه پیامی رو رمز میکنید و برای یه نفر میفرستید ، هیچ کس نباید قادر به خوندن اون پیام باشه الا مخاطبتون (تعریف محرمانگی) حالا وقتی شما این پیام که محتواش متن قابل خوندنیه میخواید به حالت رمز شده در بیارید ، به این عمل میگن رمزنگاری یا Encryption ، به پیام اولیه که قابل خوندنه میگن Plain text یا clear text و به پیام رمزشده که قابل فهم نیست میگن Cipher Text ، به عمل برگردوندن دیتا از حالت رمز شده به ساده هم میگن Decryption

رمزنگاری در زمان قدیم به همین سادگی بوده و به نظرتون مشکل کجاعه ؟ روش جایگشتی جولیو سزار رو که خاطرتون هست ؟ فرض کنید جولیو سزار به یک نفر میخواست نامه بده ، خب این مشکل نیست ، اما اگر بخواد به 5 نفر پیام بده چی؟ بازم میگید مشکلی نیست چون میتونه جایگشت پیام هارو عوض کنه ، برای مخاطب اول حروف رو یک کلمه عوض کنه برای مخاطب دوم هم دوتا تا مخاطب پتجم ، اگر بگیم به 50 تا مخاطب بخواد بفرسته چی ؟ اینجا به مشکل میخوره ! چون کلا ما 26 حرف بیشتر نداریم :) اینجاست که رمزنگاری متقارن میاد نکته : اگر بخوایم صرفا از این حالت استفاده کنیم یجورایی انگار داریم فقط Encode میکنیم ، نه ؟

عکس 2
عکس 2

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

الگرتیم هایی که باهم میبینیم توسط شخص ساخته نمیشه و ساخته شدن الگریتم توسط یه نفر بسیار خطرناکه ، فرایند ساخته شدن الگریتم کامل تو بخش پیشرفته کاور میشه ولی بدونید که فرایند ساخت و تایید و تست یک الگریتم چندین سال طول میکشه و توسط چندین نفر انجام میشه ! متخصصان حرفه ای در زمینه رمزنگاری و امنیت و مخصوصا ریاضی !

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

رمزنگاری متقارن :

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

عکس 3
عکس 3

خب حالا بیایید یکم علمی تر وارد بحث رمزنگاری متقارن بشیم ، یه مثال ریاضی ساده میزنم ، ما میخوایم عدد 3 رو که Plain Text ما هست رمز کنیم ، الگریتممون ضرب هست و کلیدمون عدد 8 ، Cipher میشه 24 درسته ؟

برای رمزگشایی دقیقا فرایند برعکس میشه ولی عینا همونه ، Cipher رو داریم و از همون الگریتم استفاده میکنیم (ولی معکوسش، این وظیفه خود اون سیستمه) کلید هم 3 و Plain Text میشه 3

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

بریم یه مثال دقیق تر بزنیم فقط قبلش بیایید 4 عمل اصلی روی بیت هارو یه مروری بکنیم :

  • NOT : این مورد هر بیتی رو برعکس خودش تبدیل میکنه ، اگر 0 باشه 1 میشه و اگر 1 باشه صفرش میکنه
NOT 1101 = 0010
  • AND :اگر دوتا عددی که مقایسه میکنه 1 باشه ، حاصل رو 1 میگذاره ، در غیر این صورت 0
1011 AND 0110 = 0010               1101 AND 1100 = 1100
  • OR : بین دوتا بیت مقایسه میکنه ، اگر حداقل یدونه 1 وجود داشت حاصل میشه 1 در غیر این صورت 0
1001 OR 1100 = 1101     1111 OR 0101 = 1111    1010 OR 0010 = 1010 
  • XOR : بین دوتا بیت مقایسه میکنه و حتما باید یکیشون 1 باشه تا حاصل بشه یک ، در غیر این صورت 0
1001 XOR 1100 = 0101          1001 XOR 1010 = 0011

فرقشون فقط توی شرط هاشونه ، AND میگه باید جفت 1 باشه تا حاصل 1 بشه ، OR میگه اگر یدونه 1 بود نتیجه یک میشه ، دوتا هم بود باز 1 میشه ، XOR میگه حتما باید یکیشون 1 باشه تا نتیجه یک بشه

عکس 4
عکس 4

خب فرض کنید مثال بالا رو ، ما فقط Plaint Text رو داریم و Key ، خودتون این دوتارو XOR کنید و میرسید به Cipher Text (اینجا الگریتم ما XOR بود) و برعکسش هم برای Decryption انجام بدید ، دقیقا همون XOR کردن و میبینید که با داشتن Cipher Text و Key میرسید به متن اصلی !

دلیلی که XOR توی رمزنگاری انقدر کاربردیه اینه که میتونیم باهاش هر مقداری رو دقیقا برعکسش کنیم ، یعنی هر مقداری رو که ما XOR میکنیم دقیقا داریم برعکسش میکنیم ، مثلا :

D=A XOR B اگر D از XOR کردن A و B بدست بیاد :

A= D XOR B و B= D XOR A

فعلا تا همین حد بدونید کافیه تا در مقالات پیشرفته براتون بازش کنم

مضایا و معایب الگریتم های رمزنگاری متقارن :

مضایا :

  • اندازه و سایز Cipher Text اندازه Plain Text ورودی خودشه ، نه بیشتر (اگر بخوایم یه فایل حجیم بفرستیم و رمزش کنیم ، این نوع الگریتم بدرد میخوره چون سایز رو بیشتر نمیکنه ! درواقع سرعت بیشتری داره )
  • سرعت پردازش محاسبات رمزنگاری متقارن روی CPU های امروزی بشدت بالاست و خیلی سریع پردازشش میکنن ، پس فرایند Encrypt و Decrypt سریع تر انجام میشه

این دوتا خاصیت الگریتم های متقارن رو برای انتقال دیتا انبوه خیلی مناسب میکنه (Bulk Data Transfer) چون دیتایی که منتقل میشه رو زیاد تر نمیکنه و فشار زیادی روی CPU از جهت پردازش نمیاره

معایب :

  • چطوری کلید رو برسونیم به طرف مقابل ؟ انتقال کلید به صورت امن (In Band) ممکن نیست و کلید رو لو میده

کمی درباره کلید های رمزنگاری :

هرچی طول کلید بیشتر باشه امنیت بیشتره ولی به مراتب سرعت میاد پایین ، حالا سوال پیش میاد که چه طولی از کلید مناسبه ؟

بیت متشکل از 0 و 1 هست ، یک کلید 40 بیتی همونطور که در تصویر میبینید از 40 تا 0 و 1 تشکیل شده ، بیش از تریلیون ها (یک با 12 صفر جلوش) ترکیب و حالت وجود داره برای این 40 بیت ولی حل کردنش برای کامپیوتر های امروزی راحته ، حالا اگر بریم سراغ 128 بیت ، میتونیم بگیم کامپیوتر های امروزی به اون قدرت نرسیدن که این کلید هارو بشکنن ، و اگر بریم سراغ کلید 1024 بیتی مطمئنی که کامپیوتری وجود نخواهد داشت که بتونه اینو بشکنه

مناسب ترین کلید ، کلید 128 بیتیه ، زیر اون اصلا جالب نیست و بالاتر از اون ضروری نیست

معرفی و شرح تفاوت Stream Cipher و Block Cipher :

ما در رمزنگاری دوتا بحث داریم ، یکیش Code هست و یکی دیگه Cipher ، وقتی صحبت از Code میشه ما منظورمون یک جدول هست که از پیش قرار داد کردیم که هر کد بیانگر چه چیزی باشه ، این امر توی بحث نظامی و پلیسی خیلی کاربرد داره ، مثلا کد 10-7 یعنی من در موقعیت هستم ، کد 10-2 یعنی به نیرو کمکی نیاز دارم و... ولی بحث Cipher کلا فرق داره ، تو الگریتم های متقارن ما دو نوع الگریتم داریم ، Stream Cipher و Block Cipher

وقتی یک پیام میخواد توسط یه الگریتم متقارن بررسی بشه ، اگر اون الگریتم Stream Cipher باشه ، میاد و پیام رو کلمه به کلمه رمز میکنه ، یا بیت به بیت رمز میکنه (محدودش یک کلمه/کاراکتریه)

ولی اگر الگریتم Block Cipher باشه روی یه قسمت کار میکنه ، مثلا روی 6 کاراکتر ، روی 6 بایت ، یعنی در دسته های 6 تایی کار میکنه بجای تکی

حالا باز Cipher ها فارغ از نوعشون ، از دو روش برای رمزکردن استفاده میکنن :

  • Substitution Ciphers : کاراکتر هارو توی پیام رو جابجا میکنن یا اصطلاحا شیفت میکنن ، مثلا اگر شیفت دو حرفه در نظر بگیریم A رو میکنن C و B رو میکنن D و...
  • Transposition Ciphers (Permutation Ciphers) : این ها میان و جابجا میکنن کاراکتر هارو ، مثلا جای A میان و P میزارن ، جای PP میان و DO میزارن و ...

این دوتا تکنیک که گفتم به کرات در الگریتم های متقارن قدیمی استفاده میشدن که باعث مبهم شدن خروجی میشد (Classical Cryptography) و الان ما دیگه میریم سراغ Modern Cryptography که دنیاش کلا متفاوته

فرق EBC و CBC در چیست ؟

قبل اینکه برسیم به استفاده از الگریتم های رمزنگاری متقارن روی فایل ها، باید اینو بگم که ما چندین حالت برای استفاده از این ها داریم، یعنی همینطوری نمیتونیم پاشیم بریم یه عکس رو با AES رمزکنیم ، باید با حالت های مختلفی از این الگریتم استفاده کنیم، ورودی های مختلف و متفاوتی بدیم که خروجی تا حد امکان امن باشه ، حالات زیادی ما داریم که من فقط اینجا دوتاشو بررسی میکنیم و بقیش توی مقاله پیشرفته : ( CBC-ECB-Counter-Galois/Counter Mode- Output feedback)

ما فقط دو حالت رو میخوایم تو الگریتم های Block Cipher بررسی کنیم :

  • ECB (Electronic Code Book) :

توی این حالت پیام ما به بلاک/بلوک های مختلفی تقسیم میشه و هر بلوک جداگانه رمز میشه ، شکستن این الگریتم راحته چون بلوک های Plain Text ورودی به تعداد معینی وارد میشن و در خروجی ما بلوک هایی با تعداد مشخص و معینی از Cipher Text داریم (بلوک همون الگریتمیه که داریم ، مثلا aes یا هرچی)

به زبان ساده بگم ، در ecb پیام به چندین بلوک تقسیم میشه و هر بلوک جداگانه با کلید رمز میشه ، این متد منسوخ شدس ، چراشو جلوتر میگم

  • CBC (Cipher Block Chaining) :

آمدن گفتن بیاییم یه کاری کنیم ، بیاییم اول بلوک بندی کنیم و بیاییم قبل رمز کردن بلوک اول ، یه IV هم قاطیش کنیم بعد Cipher Text بگیریم(یعنی میشه Plain Text + IV و این میره توی الگریتم و با کلید رمز میشه) ،(IV رو همون Salt در نظربگیرید) ، برای بلوک های بعدی حالا نتیجه یا Cipher Text بلوک قبلی رو به عنوان IV در بلوک بعدی استفاده کنیم و همینطوری تا ته !

نکته : توی cbc برای مخلوط کردن Plain Text و IV ما این دوتارو باهم XOR میکنیم

برای اینکه بیشتر با فرق ecb و cbc آشنا بشید ، من آمدم عکس خودمو با استفاده از الگریتم aes-256-ecb رمز کردم و نتیجش شده عکس وسطی ، با الگریتم aes-256-cbc هم رمز کردم و نتیجش شده عکس آخر یا همون سمت راستی ، خودتون ببینید چطوری نوع ecb میتونه باعث شه الگریتم خروجیش ضعیف بشه !

نکته : پس تا اینجا یادگرفتیم که وقتی میگیم امنیت یک الگریتم رمزنگاری ، ما هم امنیت ساختار خود الگریتمو در نظر میگیریم ، هم امنیت حالتشو ، هم امنیت طول کلیدشو ! پس شد سه تا جزء !


معرفی الگریتم های رمزنگاری متقارن :

1- DES : Data Encryption Standard

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

الگریتم DES از نوع Block Cipher هست و دسته های 64 بیتی کار میکنه

2- 3DES :

این الگریتم میاد سه بار از DES استفاده میکنه ، به این صورت که دربار اول میاد یک کلید میده و Cipher Text رو میگیره و به عنوان Plain Text مجدد میده به DES با یه کلید ، خروجی Cipher Text دومی رو هم باز مجدد به صورت Plain Text میده به DES با یه کلید دیگه

دقت کنید که برای امنیت بیشتر باید سه تا کلید متفاوت باشن ، وگر ن امنیتش با DES فرقی نمیکنه ! چرا؟ چون هر کلید 56 بیته ، اگر دوتا کلید متفاوت استفاده بشه ، کلیدمون 112 بیت بوده و زیر 128 عه پس امنیت نداره ، اگر سه تا 56 تا بشه میشه 168 تا که بالاتر از 128 تاعه پس اوکیه

به روشی که استفاده میکنه میگن EDE (Encryption-Decryption-Encryption) ، نکته ای که هست اینه که بلوک دوم ، بجای اینکه صرفا رمز بکنه ، میاد رمزگشایی میکنه ، منتها با یه کلید متفاوت ، پس اینطوری شد :

بلوک اول با کلید 1 میاد و P رو میکنه C و میده بلوک دوم ، بلوک دوم با کلید 2 میاد ورودی قبل رو بجای رمزکردن اینبار رمزگشایی میکنه با کلید 2 که نتیجه میشه یه P جدید ،و بلوک سه با کلید 3 میاد و این P بلوک قبل رو رمزنگاری میکنه و میکنه P نهایی

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

امنیت این الگریتم تا سال 2030 درنظر گرفته شده ، مثل DES از نوع Block Cipher هست و روی دسته های 64 بیتی کار میکنه

3 - Blowfish :

این الگریتم به عنوان جایگزینی برای DES معرفی شد ، مثل DES از نوع Block Cipher هست و روی دسته های 64 بیتی کار میکنه ،طول کلیدش متغییره ، از 32 بیت تا 448 بیت ، ولی بخاطر کشف یه سری حملات و ضعف ها از خود الگریتم ، دیگه ایمن نیست

4 - Twofish :

این هم دقیقا همون کسی که Blowfish رو ساخت ، ساخته و بعد نا ایمن بودن الگریتمش رفت سراغ این الگریتم و این رو توسعه داد ، قرار بود جایگزین DES بشه که در نهایت به AES باخت

این الگریتم Block Cipher هست و روی دسته های 128 بیتی کار میکنه ، طول کلیدش از 128 شروع میشه تا 256 بیت و هنوزم الگریتم امنی شناخته میشه

5 - RC4 & RC6 :

یک الگریتم رمزنگاری بسیار خوب که بیشتر کاربردش تو رمزنگاری ارتباطات شبکه بود (و هست)، این الگریتم برای رمزنگاری شبکه های وایرلس WEP - WPA استفاده شده ، همچنین از اون در SSL و TLS هم استفاده میشده ولی الان دیگه امن نیست چون توی الگریتم حفره امنیتی پیدا شده

این الگریتم از نوع Stream Cipher هست و کلیدش از 40 بایت تا 2048 بایت قابل تغییره

الگریتم RC4 که از رده خارج شد جاش RC5 و بعدش RC6 آمد که بسیار هم امن هست و روی بلوک های 128 بیتی کار میکنه و کلیدشم از 128 بیته تا 256

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

6 - AES : Advanced Encryption Standard - Rijndael

الگریتم سوم که الگریتم بسیار امنی هم هست و کلید های 128 - 194 و 256 بیتی تولید میکنه و امروزه اکثر جاها ازش استفاده میشه و استاندارد ترین الگریتمه !

این الگریتم هم در دسته Block Cipher قرار میگیره و روی دسته های 128 بیتی کار میکنه

7 - ChaCha20 :

قبل ChaCha20 ما الگریتم داشتیم به اسم SalSa20 که خیلی سریع و خوب هم بود،گوگل آمد و ChaCha20 رو به عنوان یه چیزی مشتق شده از SalSa20 ساخت و امنیت و سرعتشم زیاد تر کرد و توی محصولاتش مخصوصا گوشی های اندرویدش ازش استفاده میکرد، چرا میکرد؟ چون قدیم ها توی پردازنده ها برای پردازش AES سخت افزار جدایی وجود نداشت ولی اخیرا با وجود قسمت مجزا در پردازنده ها برای محاسبات رمزنگاری AES ، دیگه زیاد ازش استفاده نمیشه، و طول کلیدی که داره 125 یا 256 بیتیه

رمزکردن پیام و فایل به صورت عملی با الگریتم متقارن :

اگر بریم سراغ ابزار openssl و خالی تایپش کنیم :

hpn# openssl
Cipher commands (see the `enc' command for more details)
aes-128-ecb aes-192-cbc rc4  des-cbc 

میگه چند تا دستور داره و هر دستور چه زیر شاخه هایی داره ، در زیر شاخه Cipher commands میبینیم چه الگریتم هایی داره ، میریم که یه پیام رو با aes-128-cbc رمز کنیم

hpn# echo hello | openssl enc -aes-128-cbc
enter AES-128-CBC encryption password:
Salted__WL����*�qS�F�uTsK��

اینجا میبینیم که نتیجه خیلی بدرد نخوره ، چرا؟ کاراکتر های باینری تو مبنای ASCII قابل نمایش نیست ، چاره چیه؟ میگیم خروجی رو به base64 بده و یه a- میزنیم تنگ دلش :

hpn# echo hello | openssl enc -aes-128-cbc -a
enter AES-128-CBC encryption password:
U2FsdGVkX19lQBY7DqqpQZ389GO9WT395f7vQJnIcF4=

اینجا درک میکنید چرا من تو مقاله دوم گفتم برای از دست نرفتن دیتا ما از Base64 استفاده میکنیم ، ما میتونیم پسورد رو هم به صورت pass- بهش بدیم ولی من ترجیهم اینه که اینکارو نکنید ، بدلیل اینکه لاگ میندازه توی ترمینال/سشنتون

به صورت پیشفرض salt هم میزنه قاطیش ، ما salt نمیخوایم پس یه nosalt- میزنیم تنگ دلش

برای Decrypt کردن پیامم کافیه d- بزنیم :

hpn# echo hello | openssl enc -aes-128-cbc -a -nosalt
enter AES-128-CBC encryption password:
ZetNr+k1nOo1ZEzAVUj+yw==

hpn# echo &quotZetNr+k1nOo1ZEzAVUj+yw==&quot | openssl enc -aes-128-cbc -a -nosalt -d
enter AES-128-CBC decryption password:
hello

برای رمز کردن فایل هم :

hpn# ls
Alice-Book1.txt  Alice-Book2.txt
hpn# openssl enc -aes-128-cbc -a -nosalt -in Alice-Book1.txt -out Alice-Book1.txt_enc
enter AES-128-CBC encryption password:

یه in- میدیم و فایل ورودی رو بهش میدیم و یه out- میدیم و فایل خروجی رو با پسوند جدید بهش میدیم

برای دیکریپت کردن هم روش همینه ولی بلعکس d-

hpn# openssl enc -aes-128-cbc -a -nosalt -d -in Alice-Book1.txt_enc -out Alice-Book1.txt
enter AES-128-CBC decryption password:

با برنامه aescrypt هم میشه فایل رو فشرده کرد ، من فقط دستورشو میزارم چون سر راست تره ، ولی openssl از هر چیزی بی نیازتون میکنه :

hpn# aescrypt -e -o Alice-Book1.aes Alicebook1.txt
hpn# aescrypt -d -o Alice-Book1.aes

همونطور که فهمیدید e- برای Encrypt و d- برای Decrypt هست

نکته : تو مطلب HMAC-HASH گفتم ما با یه کلید میاییم هش میگیریم و به این روش میگن HMAC ، خاطرتون هست ؟ جفت کلیدا یکی بود دیگه؟ پس ما در HMAC از HASH و رمزنگاری متقارن باهم استفاده کردیم :)

در مطلب بعدی سراغ رمزنگاری نامتقارن و رمزنگاری ترکیبی و بحث تبادل کلید میریم ، هر سوال یا انتقادی بود در خدمتم ، یاعلی