קריפטוגרפיית מפתח סימטרי
בשיעור זה נבחן את קריפטוגרפיית מפתח סימטרי, המאבטחת חלק גדול מהנתונים בשקיפה ובתנועה בשל יעילותה.
בסיום השיעור נסקור:
- מהי קריפטוגרפיית מפתח סימטרי
- דוגמאות קוד Python המדגימות שימוש בקריפטוגרפיית מפתח סימטרי
- סקירת יישומים של קריפטוגרפיית מפתח סימטרי
- יישומי קריפטוגרפיית מפתח סימטרי
- האבטחה של קריפטוגרפיית מפתח סימטרי
- איומים על אלגוריתמים אלה ממחשבים קלאסיים ומחשבים קוונטיים
מבוא לקריפטוגרפיית מפתח סימטרי
קריפטוגרפיית מפתח סימטרי (SKC) היא הצורה הוותיקה והאינטואיטיבית ביותר של קריפטוגרפיה. עם SKC, מידע סודי מאובטח באמצעות הצפנת מפתח סימטרי (SKE), כלומר, שימוש במפתח סודי יחיד הן להצפנה והן לפענוח.
SKC כוללת:
- פונקציית הצפנה הממירה מופע טקסט ברור נתון ל-ciphertext תוך שימוש במפתח סודי
- פונקציית פענוח ההופכת את הפעולה על ידי המרת ה-ciphertext חזרה לטקסט ברור באמצעות אותו מפתח סודי
טקסט ברור יכול להתכוון לכל סוג של נתונים לא מוצפנים כגון טקסט שפה טבעית או קוד בינארי שתוכן המידע שלו נגיש באופן עקרוני ישירות, ואילו ciphertext מתייחס לנתונים מוצפנים שתוכן המידע שלהם אמור להיות בלתי נגיש לפני הפענוח.
אלגוריתם המתאר את פעולות ההצפנה והפענוח באמצעות מפתח סודי משותף נקרא גם צופן סימטרי.
איור 1. הצפנת מפתח סימטרי של טקסט ברור נתון ל-ciphertext ופענוח חזרה לטקסט ברור באמצעות אותו מפתח.
תכונות של מערכות קריפטוגרפיות מפתח סימטרי
מערכת קריפטוגרפית מפתח סימטרי צריכה להבטיח את התכונות הבאות לאבטחת הודעות — הן נתונים המאוחסנים בשקיפה והן תקשורת על פני ערוץ שידור כלשהו:
- סודיות: מתייחסת לתכונה לפיה תוכן המידע של הודעות מוצפנות מוגן מפני גישה בלתי מורשית.
- שלמות: מתייחסת לתכונה לפיה כל חבלה בהודעות מוצפנות במהלך אחסון או שידור ניתנת לזיהוי.
- אותנטיות: מתייחסת לתכונה לפיה מקבל הודעה יכול לאמת את זהות השולח ולזהות התחזות מצד גורם בלתי מורשה.
בנוסף, תכונות אלה צריכות להתממש בסביבה שבה האלגוריתמים או הצופנים המשמשים להצפנה ולפענוח עשויים להיות ציבוריים ושבה הגישה לתוכן המידע של הודעות מוצפנות נשלטת אך ורק דרך גישה למפתח הסודי.
יישום מערכת קריפטוגרפית מפתח סימטרי מאובטחת כולל לכן שתי משימות עיקריות:
- שימוש באלגוריתם הצפנת מפתח סימטרי חזק העמיד בפני התקפות קריפטוגרפיות.
- הבטחת סודיות בהפצה ובניהול המפתחות הסודיים.
בשיעור זה נדון בהיבטים הקשורים למשימה הראשונה, המהווה את הדאגה העיקרית של טכנולוגיית SKC. המשימה השנייה, עם זאת, דורשת פתרונות שאינם בתחום SKC עצמה ויוצגו בהמשך.
הדגמת הצפנת מפתח סימטרי ב-Python
נציג דוגמה פשוטה של פעולות ההצפנה והפענוח באמצעות צופן הזזי קיסר הקלאסי ותקן ההצפנה המתקדם המודרני (AES), שהיה התקן להצפנת מפתח סימטרי מאז 2001. ראשית נגדיר כמה ספריות Python המספקות את צופני ההצפנה הנדרשים, ולאחר מכן נגדיר את הטקסט הברור שברצוננו להצפין.
# Added by doQumentation — required packages for this notebook
!pip install -q cryptography numpy secretpy
# Install the library if needed
# %pip install secretpy
# import the required crypto functions which will be demonstrated later
from secretpy import Caesar
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
from functools import reduce
import numpy as np
# Set the plaintext we want to encrypt
plaintext = "this is a strict top secret message for intended recipients only"
print(f"\nGiven plaintext: {plaintext}")
נראה כיצד להצפין ולפענח אותו בשתי שיטות הצפנת מפתח סימטרי שונות:
- צופן ההזזה הקלאסי של קיסר
- פרוטוקול AES-256 התקן להצפנה מתקדמת המודרני
צופן ההזזה של קיסר:
הצפנת ההזזה של קיסר כוללת הגדרת
- אלפבית של תווים אפשריים לקידוד
- ערך הזזה שיכול להיות בין 0 (לא מוצפן) לאורך האלפבית. אנחנו מתייחסים לכך כמפתח.
הוא ידוע כצופן החלפה חד-אלפביתי מכיוון שכל אות מהטקסט הברור מוחלפת באחרת ב-ciphertext.
בדוגמה זו נשתמש באותיות קטנות של האלפבית.
נתחיל בהגדרת הדברים.
# initialize the required python object for doing Caesar shift encryption
caesar_cipher = Caesar()
# Define the shift, ie the key
caesar_key = 5
print(f"Caesar shift secret key: {caesar_key}")
# Define the alphabet
alphabet = (
"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",
" ",
)
print(f"alphabet: {alphabet}")
נצפין את הטקסט הברור כ די לקבל ciphertext עבור צופן קיסר.
caeser_ciphertext = caesar_cipher.encrypt(plaintext, caesar_key, alphabet)
print(f"Encrypted caeser shift ciphertext: {caeser_ciphertext}")
נפענח את ה-ciphertext חזרה לטקסט הברור המקורי באמצעות אותו מפתח שהשתמשנו בו להצפנה.
caeser_plaintext = caesar_cipher.decrypt(caeser_ciphertext, caesar_key, alphabet)
print(f"Decrypted caeser shift plaintext: {caeser_plaintext}\n")
צופן תקן ההצפנה המתקדם (AES)
כעת נצפין את הטקסט הברור באמצעות AES, אלגוריתם הצפנת מפתח סימטרי פופולרי.
נתחיל ביצירת המפתח, במקרה זה, מחרוזת של 16 תווים אקראיים.
# lambda defines an inline function in this case that takes two values a,b with the resulting expression of a+b
# reduce uses a two-argument function(above), and applies this to all the entries in the list (random alphabet characters) cumulatively
aes_key = reduce(lambda a, b: a + b, [np.random.choice(alphabet) for i in range(16)])
print(f"AES secret key: {aes_key}")
AES תומך במספר מצבי פעולה ומחייב אותנו לציין איזה להשתמש.
אנחנו בוחרים במצב Cipher Block Chaining (CBC) המסופק על ידי מחלקה modes.CBC של ספריית cryptography. מצב CBC של AES משתמש באקראיות לאבטחה נוספת. זה מחייב ציון וקטור אתחול אקראי (IV), הנקרא גם nonce. נשתמש גם כאן במחרוזת אקראית, בדיוק כפי שעשינו עבור המפתח.
aes_initialization_vector = reduce(
lambda a, b: a + b, [np.random.choice(alphabet) for i in range(16)]
)
print(f"AES initialization vector: {aes_initialization_vector}")
כעת נוכל ליצור מופע של צופן AES בשם שולח ההודעה הסודית. שים לב שוקטור האתחול מועבר למחלקה modes.CBC להגדרת מצב הפעולה CBC.
לאחר מכן נצפין את הטקסט הב רור לשליחה.
# The encryptor is setup using the key and CBC. In both cases we need to convert the string (utf-8) into bytes
sender_aes_cipher = Cipher(
algorithms.AES(bytes(aes_key, "utf-8")),
modes.CBC(bytes(aes_initialization_vector, "utf-8")),
)
aes_encryptor = sender_aes_cipher.encryptor()
# update can add text to encypt in chunks, and then finalize is needed to complete the encryption process
aes_ciphertext = (
aes_encryptor.update(bytes(plaintext, "utf-8")) + aes_encryptor.finalize()
)
# Note the output is a string of bytes
print(f"Encrypted AES ciphertext: {aes_ciphertext}")
כדי לפענח אותו, ניצור מופע של צופן AES בשם המקבל. שים לב שלמקבל המיועד יש גישה הן למפתח הסודי והן לוקטור האתחול, אך האחרון אינו נדרש להיות סודי.
# Similar setup of AES to what we did for encryption, but this time, for decryption
receiver_aes_cipher = Cipher(
algorithms.AES(bytes(aes_key, "utf-8")),
modes.CBC(bytes(aes_initialization_vector, "utf-8")),
)
aes_decryptor = receiver_aes_cipher.decryptor()
# Do the decryption
aes_plaintext_bytes = aes_decryptor.update(aes_ciphertext) + aes_decryptor.finalize()
# convert back to a character string (we assume utf-8)
aes_plaintext = aes_plaintext_bytes.decode("utf-8")
print(f"Decrypted AES plaintext: {aes_plaintext}")
יישומים של קריפטוגרפיית מפתח סימטרי
בעוד שצופנים קלאסיים כגון צופן קיסר יצאו מכלל שימוש מזמן, מערכות קריפטוגרפיות סימטריות מודרניות כגון AES פרוסות במגוון רחב של יישומים, כולל:
-
הצפנה ופענוח של נתונים: SKC נמצאת בשימוש נרחב להגנה על נתונים רגישים, בין אם מאוחסנים בשקיפה על מכשיר ובין אם מועברים על פני רשת. דוגמאות כוללות הגנה על אישורי משתמשים, הצפנת הודעות דואר אלקטרוני ואבטחת עסקאות פיננסיות, בין היתר.
-
תקשורת מאובטחת: פרוטוקולי תקשורת נפוצים כגון SSL/TLS משתמשים בשילוב של הצפנת מפתח סימטרי וא-סימטרי כדי להבטיח את הסודיות והשלמות של הנתונים המוחלפים בין שני צדדים. הודעות אלו מוצפנות ומפוענחות באמצעות הצפנת מפתח סימטרי המשתמשת במפתח משותף. המפתח המשמש בהצפנת מפתח סימטרי מוחלף בצורה מאובטחת באמצעות הצפנת מפתח א-סימטרי המשתמשת בזוג מפתחות ציבורי-פרטי. הצפנת מפתח סימטרי מהירה הרבה יותר ולכן ניתן להשתמש בה להצפנת הודעות בגודל גדול.
-
אימות אותנטיות: בסביבות מסוימות, SKC מיושמת באמצעות טכניקות כגון קודי אימות הודעות (MACs) וקודי MAC עם גיבוב ממוין (HMAC) כדי לאמת את האותנטיות והשלמות של הודעות, ומבטיחה תקשורת עמידה בפני חבלה.
-
הצפנת קבצים ודיסקים: תוכנות הצפנת דיסק מלא וכלי הצפנת קבצים משתמשים ב-SKC להגנה על נתונים רגישים המאוחסנים על דיסקים קשיחים או התקני אחסון ניידים.
-
רשתות פרטיות וירטואליות: טכנולוגיות VPN, שנועדו לספק ערוצי תקשורת סודיים ללא ציתות, יכולות להשתמש בהצפנת מפתח סימטרי או א-סימטרי לחיבור משתמשים מרוחקים וכן רשתות ארגוניות.
מגוון היישומים הרחב שבהם SKC פרוסה מחייב בתורה שמערכות קריפטוגרפיות סימטריות יעמדו בסט מסוים של קריטריונים.
עקרונות הצפנת מפתח סימטרי
בחלק זה נדון בכמה מהעקרונות הבסיסיים העומדים בבסיס אבטחת אלגוריתמי הצפנת מפתח סימטרי.
עמידות בפני התקפת כוח גס: הדרישה הבסיסית ביותר לאבטחה של צופן הצפנה היא שגודל מרחב המפתחות — במילים אחרות, מספר המפתחות הנבדלים האפשריים שמשתמש באלגוריתם יכל לבחור מהם — הוא גדול מאוד.
עמידות בפני התקפת קריפטניליזה: הדרישה הבסיסית השנייה לצופן, סימטרי או אחר, היא שהוא יכול לייצר ciphertexts שבלתי ניתנים לפענוח מבחינת מידע. לשם כך, תנאי הכרחי אך לא מספיק מנקודת מבט תיאורית מידע הוא שה-ciphertexts צריכים להיות מאופיינים על ידי אנטרופיה גבוהה, מה שהופך אותם לבלתי ניתנים להבחנה מטקסט אקראי ללא דפוסים או קורלציות ניתנים לזיהוי. בכך, תוקף לא יכול לקבל מידע על הטקסט הברור או המפתח הסודי על ידי ניסיון לנתח את ה-ciphertext באמצעות ניתוח תדרים או טכניקות סטטיסטיות אחרות.
עמידות בפני צורות כלליות של התקפות קריפטאנליזה מספיקה להבטחת אבטחה סמנטית מפורשת דרך המושג אי-הבחנה. בעוד שישנן מספר גרסאות של אי-הבחנה עם דרישות שונות, מערכת קריפטוגרפית סימטרית נחשבת מאובטחת סמנטית אם היא מספקת את הקריטריון של אי-הבחנה תחת התקפת טקסט ברור מוכר (IND-CPA). משמעות הדבר היא שתוקף לא יכול להבחין בין ההצפנות של שתי הודעות שונות גם אם מורשה לשלוח טקסטות ברורות מרובות לבחירתו לאלגוריתם ולראות את ה-ciphertexts המתאימים.
כפי שנשקול בהמשך, IND-CPA מחייב בדרך כלל שימוש באקראיות כדי להבטיח שבכל פעם שטקסט ברור נתון מוצפן עם מפתח סודי נתון, ה-ciphertext המתקבל יהיה שונה בצורה בלתי צפויה עבור כל הצפנה.
מצבי כשל של צופנים קלאסיים: לפני הופעת הקריפטוגרפיה המודרנית בשנות ה-70, רוב הצופנים הקלאסיים בשימוש מעשי לא עמדו באחת משתי הדרישות לעיל או בשתיהן. לדוגמה, צופני החלפה מוקדמים כגון צופן ההזזה החד-אלפביתי של קיסר אופיינו הן בגודל מרחב מפתחות קטן (ראה טבלה 1) והן ב-ciphertext בעל אנטרופיה נמוכה, מה שהפך אותם לא מאובטחים בפני מגוון התקפות קריפטאנליטיות כגון התקפות כוח גס, ניתוח תדרים והתקפות טקסט ברור מוכר (KPT).
צופני החלפה רב-אלפביתיים מאוחרים יותר כגון צופן Vigenère וצופן מכונת האניגמה הציגו גדלי מרחב מפתחות גדולים למעשה, מה שהפך אותם לעמידים בפני התקפות כוח גס, אך היו פגיעים לניתוח תדרים ולהתקפות KPT, בהתאמה. בדומה לצופני ההחלפה, צופני ערבוב קלאסיים, המסדרים מחדש אותיות בהודעה במקום להחליף אותן, נפגעים גם הם על ידי מגוון התקפות כגון אנאגרמינג, ניתוח סטטיסטי, כוח גס והתקפות KPT, בין היתר.
תיאורטית, צופן החלפה רב-אלפביתי המכונה one-time pad (OTP) ידוע כמאובטח קריפטוגרפית. OTP מציג מפתח סודי שצריך להיות (1) מורכב מאותיות או ביטים שנבחרו באקראי, (2) ארוך לפחות כמו הטקסט הברור המקורי, ו-(3) בשימוש פעם אחת בלבד. OTP אינו מעשי ליישומים בפועל מכיוון שאם ניתן היה לשתף בצורה מאובטחת את המפתח הסודי — הנדרש להיות ארוך כמו הטקסט הברור וניתן לשימוש פעם אחת בלבד — אז ניתן היה לשתף גם את הטקסט הברור המקורי. OTP במקום זאת ממחיש את השימוש באקראיות ביצירת ciphertexts מאובטחים.
תוקף המנסה לבצע חיפוש כוח גס דרך מרחב המפתחות כדי למצוא מפתח שמפענח את ההודעה חייב לבצע מספר פעולות פרופורציונלי לגודל מרחב המפתחות.
לכן, מרחב מפתחות גדול מספק עמידות בפני התקפות כוח גס על ידי הפיכתן לחיסרון חישובי. טבלה 1 מפרטת את גדלי מרחב המפתחות של כמה צופנים ידועים.
טבלה 1: גדלי מרחב מפתחות של כמה צופנים סימטריים
| צופן | אורך מפתח | גודל מרחב מפתחות |
|---|---|---|
| זזי קיסר | 1 | גוד ל-האלפבית |
| Vigenere | n | גודל-האלפבית |
| One-time-pad | אורך-הטקסט-הברור | גודל-האלפבית |
| DES | 56 | 2 |
| AES-128 | 128 | 2 |
| AES-192 | 192 | 2 |
| AES-256 | 256 | 2 |
| ChaCha20 | 256 | 2 |
| שיטות הצפנת מפתח סימטרי מודרניות מתגברות במידה רבה על מגבלות הצופנים הקלאסיים. הן מייצרות ciphertext עמיד בפני קריפטאנליזה ומציגות גדלי מרחב מפתחות גדולים תוך שהן יעילות הרבה יותר מבחינה מעשית מOTP. |
צופני בלוק: מחלקה אחת של צופנים מודרניים — כגון DES ו-AES — משיגה אבטחה על ידי שילוב עקרונות הבלבול והפיזור שהוצגו במקור על ידי קלוד שאנון. נדון במושגים אלה בהגדרה שבה שיטות הצפנה עובדות עם ייצוגים בינאריים של הודעות:
-
בלבול: בלבול הוא המאפיין לפיו כל ביט ב-ciphertext תלוי בביטים מרובים של המפתח הסודי. הוא מבטיח שגם שינוי קטן במפתח הסודי ישנה כמעט את כל הביטים של ה-ciphertext, ומטשטש את הקשר בין ה-ciphertext למפתח הסודי.
-
פיזור: פיזור הוא המאפיין לפיו היפוך ביט אחד בטקסט הברור צריך לשנות בערך חצי מהביטים ב-ciphertext ולהיפך. הפיזור מסתיר קשרים סטטיסטיים בין הטקסט הברור ל-ciphertext. לצופנים עם פיזור מספיק מתממש מה שנקרא קריטריון המפולת של הקריפטוגרפיה.
צופני בלוק מיישמים בלבול ופיזור באמצעות מבנים קריפטוגרפיים הידועים כרשתות החלפה-תמורה (SPNs) הפועלות על בלוקים דיסקרטיים של נתונים.