דילוג לתוכן
New

DeepSeek V4.1 Flash free for 7 days: 10M tokens a day after a top-up of $10 or more. Until Nov 30.

How it works

מהו צופן קיסר? דוגמה פשוטה ולמה הוא לא מאובטח

צופן קיסר מזיז כל אות מספר קבוע של מקומות. מצפינים את HELLO ל-KHOOR ביד, הופכים את הפעולה ובודקים למה השיטה נשברת.

מתחילים3 דקות קריאהמאת NotHoly

צופן קיסר הוא צופן החלפה. כל אות מוחלפת באות אחרת שנמצאת מספר קבוע של מקומות ממנה באלפבית. מזיזים כל אות שלושה מקומות קדימה, והתוצאה של HELLO היא KHOOR. השם בא מיוליוס קיסר, שלפי המסורת נהג להצפין כך את ההודעות שלו. הצופן פשוט מספיק לעבודה ביד, ובגלל הפשטות הזאת הוא כמעט לא נותן אבטחה.

הצפנה ביד

כותבים את האלפבית בשורה אחת. בשורה שנייה כותבים את אותו אלפבית מוזז בשלושה מקומות, וחוזרים להתחלה אחרי Z:

text
Plain:  ABCDEFGHIJKLMNOPQRSTUVWXYZ
Shift:  DEFGHIJKLMNOPQRSTUVWXYZABC

כדי להצפין, מאתרים כל אות של הטקסט הגלוי בשורה העליונה ומעתיקים את האות שמתחתיה. H הופכת ל-K, ‏E הופכת ל-H, ‏L הופכת ל-O ו-O הופכת ל-R. כך התוצאה של HELLO היא KHOOR. המפתח הוא גודל ההזזה, כאן 3.

רווחים, ספרות וסימני פיסוק לא נמצאים באלפבית שבין A ל-Z. גרסה לימודית יכולה להשאיר אותם כמו שהם, וקוד ה-Python שבהמשך עושה בדיוק את זה.

פענוח

הפענוח הוא אותה טבלה בכיוון ההפוך. מזיזים כל אות שלושה מקומות אחורה, וזה שקול להזזה של 23 מקומות קדימה:

text
KHOOR  →  HELLO

עבור מפתח נתון, כל אות של הטקסט הגלוי ממופה לאות אחת בלבד של הטקסט המוצפן, וגם המיפוי ההפוך חד־משמעי. לכן אפשר לבטל את הצופן ברגע שיודעים את המפתח.

הזזות שליליות וגדולות

באלפבית האנגלי יש 26 אותיות, ולכן ההזזות חוזרות על עצמן כל 26 מקומות. הזזה של 29 עושה את אותו הדבר כמו הזזה של 3:

text
29 mod 26 = 3

הזזה של −3 עושה את אותו הדבר כמו הזזה של 23. בקוד כדאי לחשב את ההזזה מודולו 26, כך שכל מספר שלם יעבוד.

גרסה קצרה ב-Python

הפונקציה הזאת מזיזה רק את האותיות A עד Z ו-a עד z, לא נוגעת בשאר התווים וחוזרת להתחלה בעזרת מודולו 26. כדי להמיר בין אותיות למספרים היא משתמשת בפונקציות ord וגם chr:

python
def caesar(text, shift):
    out = []
    for ch in text:
        if ch.isascii() and ch.isalpha():
            base = ord('A') if ch.isupper() else ord('a')
            out.append(chr((ord(ch) - base + shift) % 26 + base))
        else:
            out.append(ch)
    return ''.join(out)

print(caesar("HELLO", 3))
print(caesar("KHOOR", -3))
print(caesar("KHOOR", 23))
print(caesar("HELLO", 29))
print(caesar("ATTACK AT DAWN", 3))
print(caesar(caesar("Hello, World!", 13), 13))
print(caesar("Hello, World!", 13))
print(caesar("hello, world", 3))
print(caesar("KHOOR", 26 - 3) == caesar("KHOOR", -3))
print(sum(1 for s in range(1, 26) if caesar("KHOOR", s) == "HELLO"))
print(caesar("HELLO", 3) == caesar("HELLO", 29))

הפלט של הרצת הסקריפט:

text
KHOOR
HELLO
HELLO
KHOOR
DWWDFN DW GDZQ
Hello, World!
Uryyb, Jbeyq!
khoor, zruog
True
1
True

הפלט מאשר את מה שנאמר בסעיפים הקודמים. הזזות של −3 ושל 23 נותנות אותה תוצאה, וכך גם 3 ו-29. מבין ההזזות 1 עד 25, רק אחת מחזירה את KHOOR לטקסט HELLO. הפעלה כפולה של הזזה 13 מחזירה את הטקסט המקורי, וזה המקרה של ROT13 שמתואר בהמשך.

למה צופן קיסר לא מאובטח

באלפבית של 26 אותיות יש רק 25 הזזות שמשנות את הטקסט. תוקף יכול לנסות את כולן ולבדוק איזו תוצאה קריאה. בטקסט באנגלית קל לזהות את התוצאה הקריאה, כך שההתקפה כמעט לא דורשת מאמץ.

גם שכיחות האותיות נשמרת אחרי ההזזה. באנגלית E נפוצה ו-Z נדירה, ולכן טקסט מוצפן שבו אות אחת מופיעה הרבה יותר מהאחרות הוא רמז חזק. גם בלי לנסות את כל ההזזות, ספירת האותיות מצביעה על המפתח.

הצופן שימושי ללימוד אוצר המילים של הקריפטוגרפיה: טקסט גלוי, טקסט מוצפן, מפתח, החלפה ו-brute force. אסור להשתמש בו כדי להגן על סיסמאות, נתוני לקוחות, מפתחות API או קבצים פרטיים. הצפנה אמיתית משתמשת באלגוריתמים מתוקננים, במפתחות שנוצרו כראוי ובניהול מפתחות זהיר. הערך על קריפטוגרפיה במילון של NIST נותן את ההגדרות הפורמליות של התחום.

צופן קיסר ו-ROT13

ROT13 הוא צופן קיסר עם הזזה של 13. הוא ההופכי של עצמו: הפעלה כפולה מחזירה את הטקסט המקורי, כי 13 + 13 = 26, וסיבוב שלם סביב האלפבית לא משנה כלום. הפלט של ROT13 על Hello, World! הוא Uryyb, Jbeyq!, כפי שמופיע למעלה.

משתמשים ב-ROT13 כדי להסתיר ספוילרים או פאנץ׳ליינים ממבט חטוף. הוא לא נותן הגנה אמיתית, כי מי שמכיר את השיטה קורא אותו תוך שניות.

לנסות בעצמך

צריך להצפין ביד את ATTACK AT DAWN עם הזזה של 3, בלי לגעת ברווחים, ולהשוות לתשובה הזאת:

text
DWWDFN DW GDZQ

אחר כך כדאי לשנות את ההזזה בפונקציית ה-Python ולהריץ אותה על אותו טקסט. כדאי לנסות הזזה 0, הזזה 26 והזזה 13, ולנחש כל תוצאה לפני ההרצה. טקסט הבדיקה צריך להיות סינתטי או שלך, והתרגיל נשאר על המחשב שלך.

המאמר הבא, צופן קיסר ב-Python, מרחיב את הפונקציה הזאת עם טיפול בקלט ובדיקות.

להמשך קריאה: הערך על קריפטוגרפיה במילון של NIST והתיעוד של Python עבור ord וגם chr.

מקורות

  1. NIST Cryptography Glossary
  2. Python documentation: Built-in Functions (ord, chr)

עוד בנושא קריפטוגרפיה

קריפטוגרפיה

סיסמאות ו-hashing עם Argon2id

למה hashes מהירים נכשלים בסיסמאות, מה salt ו-work factor עושים, ואיך מחשבים ומאמתים Argon2id ב-Python עם argon2-cffi.

ביניים8 דקות קריאה