HashTheory

رمزنگاری سزار به زبان ساده

چطور با جابه‌جایی ساده‌ی حروف، یک پیام را رمزگذاری کنیم؟

هومن خطیب زاده

هومن خطیب زاده

۳ بازدید
An abstract illustration of a multi-tiered cryptographic encryption

رمز سزار از کجا آمد؟

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

امروزه برای این کار از الگوریتم‌های بسیار پیچیده، کلیدهای رمزنگاری، توابع ریاضی و کامپیوترهای قدرتمند استفاده می‌کنیم. اما انسان‌ها هزاران سال قبل هم همین مشکل را داشتند، فقط ابزارهایشان خیلی ساده‌تر بود. یکی از معروف‌ترین راه‌حل‌های قدیمی، رمز سزار یا Caesar Cipher است.

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

ایده به این صورت است که هر حرف را سه خانه جلو ببریم:

Text
A → D
B → E
C → F
D → G
...

در نتیجه مثلاً HELLO تبدیل می‌شود به KHOOR. گیرنده‌ای که می‌داند مقدار جابجایی ۳ است، می‌تواند همین مسیر را برعکس کند و پیام اصلی را به دست بیاورد.

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

رمز سزار دقیقاً چیست؟

رمز سزار یکی از ساده‌ترین نمونه‌های رمزهای جایگزینی یا Substitution Cipher است. در رمزهای جایگزینی، یک حرف از متن اصلی را با حرف دیگری جایگزین می‌کنیم. اما رمز سزار یک قانون بسیار ساده دارد:

هر حرف را به اندازه یک مقدار ثابت در الفبا جابجا کن.

این مقدار ثابت را شیفت یا کلید می‌نامیم.

فرض کنید شیفت ما 3 باشد. الفبای انگلیسی را در نظر بگیرید:

Text
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

حالا هر حرف را سه خانه جلو می‌بریم:

ADBECFDGEH...\begin{aligned} \text{A} &\to \text{D} \\ \text{B} &\to \text{E} \\ \text{C} &\to \text{F} \\ \text{D} &\to \text{G} \\ \text{E} &\to \text{H} \\ ... \end{aligned}

اما یک سؤال مهم پیش می‌آید، اگر به Z برسیم چه می‌شود و اضافه کردن شیفت ۳ چه نتیجه‌ای می‌دهد؟
در چنین موقعیت‌هایی از ایده حساب پیمانه‌ای یا Modular Arithmetic در ریاضیات استفاده می‌کنیم. یعنی الفبا را مثل یک دایره تصور می‌کنیم که از انتهای آنها دوباره به ابتدای الفبا وارد می‌شویم.

رمز سزار چگونه کار می‌کند؟

برای اینکه کار رمز سزار را دقیق‌تر بفهمیم، حروف را به عدد تبدیل می‌کنیم:

A=0B=1C=2D=3    Z=25\begin{aligned} \text{A} &= 0 \\ \text{B} &= 1 \\ \text{C} &= 2 \\ \text{D} &= 3 \\ &\;\;\vdots \\ \text{Z} &= 25 \end{aligned}

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

فرمول رمزگذاری:

En(x)=(x+n)(mod26)E_n(x) = (x + n) \pmod{26}

یعنی حرف را به اندازه n خانه ببر جلو

و برای رمزگشایی:

Dn(x)=(xn)(mod26)D_n(x) = (x - n) \pmod{26}

یعنی حرف را به اندازه n خانه ببر عقب

عدد 26 هم به این دلیل است که الفبای انگلیسی ۲۶ حرف دارد.

مثال

فرض کنیم رضا می‌خواهد برای احمد پیامی بفرستد و هر دو از قبل روی شیفت ۳ توافق کرده‌اند.

پیام رضا: CALL ME TOMORROW

حالا هر حرف را سه خانه جلو می‌بریم:

CFADLOLO\begin{aligned} \text{C} &\to \text{F} \\ \text{A} &\to \text{D} \\ \text{L} &\to \text{O} \\ \text{L} &\to \text{O} \end{aligned}

پس CALL تبدیل می‌شود به FDOO

به همین شکل ME می‌شود PH و TOMORROW می‌شود WRPRUURZ.

در نتیجه ما همچین پیامی داریم: ‍FDOO PH WRPRUURZ

اگر احمد بداند که شیفت 3 است، کافی است همین کار را برعکس انجام دهد تا به پیام اصلی برسد.

FDOOCALLPHMEWRPRUURZTOMORROW\begin{aligned} \text{FDOO} &\to \text{CALL} \\ \text{PH} &\to \text{ME} \\ \text{WRPRUURZ} &\to \text{TOMORROW} \end{aligned}

پس رمز سزار در اصل یک بازی بسیار ساده با جایگاه حروف در الفباست.

چرا mod26mod {26} را لازم داریم؟

فرض کنید حرف T را با شیفت 9 رمزگذاری کنیم. در سیستم عددی T = 19 است.حالا ۹ واحد به جلو می‌رویم، به عبارتی 19 + 9 = 28 . اما عدد ۲۸ در محدوده‌ی 0 تا 25 قرار ندارد. بنابراین از mod 26 استفاده می‌کنیم:

28mod26=228 \bmod 26 = 2

عدد ۲ یعنی حرف به c مربوط می‌شود. به عبارتی:

012ABC\begin{array}{ccc} 0 & 1 & {\color{#00e676} 2} \\ \downarrow & \downarrow & {\color{#00e676} \downarrow} \\ \text{A} & \text{B} & {\color{#00e676} \text{C}} \end{array}

بنابراین mod 26 فقط یک روش ریاضی برای بیان همین «برگشتن به ابتدای الفبا» است.

پیاده‌سازی رمز سزار با پایتون

تا اینجا دیدیم که رمز سزار از یک ایده‌ی بسیار ساده استفاده می‌کند، مقدار عددی هر حرف را به اندازه‌ مشخصی جابجا می‌کنیم و با mod 26 مطمئن می‌شویم که بعد از Z دوباره به ابتدای الفبا برگردیم. حالا همین ایده را با چند خط کد پایتون پیاده‌سازی می‌کنیم.

Python
def caesar_encrypt(text, shift):
    result = ""

    for char in text:
        if char.isalpha():
            base = ord('A') if char.isupper() else ord('a')
            result += chr((ord(char) - base + shift) % 26 + base)
        else:
            result += char

    return result


message = "HELLO WORLD"
encrypted = caesar_encrypt(message, 3)

print(encrypted)

خروجی:

Text
KHOOR ZRUOG

می‌توان رمز سزار را برای فارسی هم استفاده کرد؟

تا اینجا تمام مثال‌های ما بر اساس الفبای انگلیسی بودند؛ بنابراین از mod 26 استفاده کردیم. اما ایده‌ی رمز سزار محدود به زبان انگلیسی نیست. اگر یک الفبا داشته باشیم که تعداد مشخصی حرف دارد، می‌توانیم همین روش را روی آن الفبا اجرا کنیم.

برای مثال، الفبای فارسی استاندارد ۳۲ حرف دارد. بنابراین اگر بخواهیم یک نسخه‌ی ساده از رمز سزار را برای فارسی طراحی کنیم، به جای mod 26 ازmode 32 استفاده می‌کنیم.

پس فرمول رمزگذاری در یک نسخه‌ ساده‌ فارسی می‌تواند به این شکل باشد:

En(x)=(x+n)(mod32)\begin{aligned} E_n(x) &= (x + n) \pmod{32} \\ \end{aligned}

و برای رمزگشایی:

Dn(x)=(xn)(mod32)\begin{aligned} D_n(x) &= (x - n) \pmod{32} \end{aligned}

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

پس ایده‌ اصلی رمز سزار را می‌توان اینطور تعمیم داد:

یک الفبای مشخص داشته باش، به هر حرف یک عدد اختصاص بده، مقدار شیفت را اضافه کن و با mod N از محدوده‌ الفبا خارج نشو.

کل ماجرای راز سزار همین بود؟

تقریباً بله! اما همین ایده‌ی ساده، چند مفهوم مهم در رمزنگاری را به ما یاد می‌دهد:

  • متن اصلی یا Plaintext
  • متن رمز‌نگاری شده یا Ciphertext
  • کلید یا Key
  • رمزگذاری یا Encryption
  • رمزگشایی یا Decryption
  • جایگزینی حروف
  • حساب پیمانه‌ای
  • فضای کلید یا Keyspace

کلید رمز سزار چیست؟

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

مثلاً اگر شیفت ما 3 باشد:

AD\text{A} \to \text{D}

اما اگر شیفت 5 باشد:

AF\text{A} \to \text{F}

بنابراین عدد شیفت نقش کلید را دارد. فرستنده و گیرنده باید روی این مقدار توافق داشته باشند. فرستنده با ۷ خانه جلو رفتن پیام را رمزگذاری می‌کند و گیرنده با ۷ خانه عقب رفتن آن را رمزگشایی می‌کند. به همین دلیل رمز سزار یک رمز متقارن (Symmetric Cipher) است؛ یعنی برای رمزگذاری و رمزگشایی از یک کلید مشترک استفاده می‌شود.

چند کلید مختلف داریم؟

اینجا اولین مشکل امنیتی رمز سزار خودش را نشان می‌دهد. الفبای انگلیسی فقط ۲۶ حرف دارد پس در نگاه اول می‌گوییم ۲۶ کلید. اما در واقع شیفت ۰ هیچ تغییری در متن ایجاد نمی‌کند و شیفت ۲۶ هم دقیقاً همان نتیجه را دارد. بنابراین تعداد شیفت‌های معنادار بسیار محدود است. برای یک مهاجم، امتحان کردن تمام حالت‌ها اصلاً کار سختی نیست.

مثلاً اگر عبارت KHOOR را در نظر بگیریم، می‌توانیم همه‌ی شیفت‌ها را امتحان کنیم:

Shift 1JGNNQShift 2IFMMPShift 3HELLOShift 4GDKKN    \begin{aligned} \text{Shift 1} &\to \text{JGNNQ} \\ \text{Shift 2} &\to \text{IFMMP} \\ \text{Shift 3} &\to \text{HELLO} \\ \text{Shift 4} &\to \text{GDKKN} \\ &\;\;\vdots \end{aligned}

یعنی بدون اینکه کلید را بدانیم، می‌توانیم تمام کلیدهای احتمالی را امتحان کنیم. این روش را Brute Force یا جست‌وجوی فراگیر می‌نامیم.

آیا فقط Brute Force مشکل رمز سزار است؟

خیر، حتی اگر تعداد شیفت‌ها بیشتر هم باشد، ساختار رمز سزار مشکل دیگری دارد. مثلا اگر AD\text{A} \to \text{D}باشد، تمام Aهای متن به D تبدیل می‌شوند. بنابراین الگوی حروف در متن تقریباً دست‌نخورده باقی می‌ماند. مثلاً اگر یک کلمه چند بار یک حرف مشخص داشته باشد، این الگو در متن رمز‌شده هم حفظ می‌شود. این ویژگی در رمزهای جایگزینی ساده باعث می‌شود بتوان از تحلیل فراوانی یا Frequency Analysis برای شکستن رمز استفاده کرد. در زبان انگلیسی بعضی حروف بسیار بیشتر از بقیه استفاده می‌شوند؛ مثلاً E یکی از پرتکرارترین حروف است.

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

رمز سزار و رمزهای پیشرفته‌تر

رمز سزار از یک ایده‌ی بسیار ساده شروع می‌شود:

حروف را جایگزین کن.

اما همین ایده بعدها به روش‌های پیچیده‌تری توسعه پیدا کرد. یکی از نمونه‌های معروف، رمز ویژنر یا Vigenère Cipher است.

در رمز سزار، همه‌ی حروف با یک مقدار ثابت جابه‌جا می‌شوند:

+3+3+3+3+3\begin{aligned} +3 \\ +3 \\ +3 \\ +3 \\ +3 \end{aligned}

اما در رمز ویژنر، مقدار جابه‌جایی می‌تواند تغییر کند:

+3+7+1+12+5\begin{aligned} +3 \\ +7 \\ +1 \\ +12 \\ +5 \\ \vdots \end{aligned}

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


آیا رمز سزار مرده است؟

اگر منظورتان این است که «آیا هنوز می‌توانیم برای محافظت از رمز عبور، پیام خصوصی یا اطلاعات بانکی از رمز سزار استفاده کنیم؟» جواب کاملاً روشن است: خیر.

رمز سزار برای امنیت واقعی مناسب نیست. امروزه حتی ابزارهای بسیار ساده می‌توانند تمام شیفت‌های ممکن را در کسری از ثانیه امتحان کنند.

اما اگر منظورتان این است که «آیا رمز سزار دیگر هیچ فایده‌ای ندارد؟» باز هم جواب نه است.

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

جمع‌بندی

رمز سزار یکی از ساده‌ترین روش‌های رمزنگاری است هر حرف را به اندازه‌ی مشخصی در الفبا جابه‌جا می‌کنیم. سادگی رمز سزار در عین حال بزرگ‌ترین ضعف آن است. از یک طرف، یادگیری و پیاده‌سازی آن بسیار آسان است؛ از طرف دیگر، فضای کلید آن بسیار کوچک است و ساختار پیام را به اندازه‌ی کافی پنهان نمی‌کند. بنابراین می‌توان آن را با روش‌هایی مانند Brute Force و Frequency Analysis به‌سادگی شکست. پس رمز سزار را نباید به عنوان یک ابزار امنیتی جدی ببینیم. رمز سزار یک نقطه‌ی شروع عالی برای فهمیدن این است که رمزنگاری اصلاً چه مشکلی را حل می‌کند و یک پیام چگونه می‌تواند از متن قابل‌خواندن به متن رمز‌شده تبدیل شود. و شاید مهم‌تر از همه، یک درس ساده به ما می‌دهد:

رمزگذاری کردن با امن کردن یک پیام یکی نیست.

هر روشی می‌تواند پیام را به شکلی نامفهوم تبدیل کند؛ مسئله‌ی اصلی این است که آیا فردی که نباید پیام را بخواند، می‌تواند آن را دوباره به متن اصلی برگرداند یا نه.