לדלג לתוכן

בונים כלי שמוכיח למה חלק מהאלגוריתמים פשוט לא בטוחים

יש בלבול ענק בין הצפנה (encryption) ל-hashing, ורוב האנשים שמשתמשים במונחים האלה בטעות אף פעם לא בדקו בעצמם למה זה משנה. בפרויקט הזה בונים כלי קטן שבודק ומשווה חוזק של אלגוריתמי hash שונים, ובתהליך מבינים בדיוק למה בחירת אלגוריתם היא לא עניין טכני שולי - היא ההבדל בין מסד נתונים סיסמאות בטוח לבין אסון שרק מחכה לקרות.

קודם כל - hashing זה לא הצפנה

הצפנה היא תהליך הפיך - מצפינים מידע עם מפתח, ומי שיש לו את המפתח יכול לפענח ולקבל את המידע המקורי בחזרה. Hashing הוא חד-כיווני - לוקחים קלט ומייצרים ממנו טביעת אצבע קבועה באורך, ואין דרך "לחזור אחורה" ולקבל את הקלט המקורי מתוך ה-hash. סיסמאות אף פעם לא אמורות להיות מוצפנות בבסיס נתונים - הן אמורות לעבור hash, כי השרת לא צריך לדעת מה הסיסמה שלכם, הוא רק צריך לבדוק שה-hash שאתם שולחים בהתחברות תואם למה ששמור.

בונים סקריפט השוואה בין אלגוריתמים

הצעד הראשון בפרויקט הוא סקריפט פייתון פשוט שמריץ אותה סיסמה דרך כמה אלגוריתמים שונים ומודד כמה זמן לוקח לחשב hash אחד:

import hashlib
import time
import bcrypt

password = b"MySecretPassword123"

start = time.time()
for _ in range(100000):
    hashlib.md5(password).hexdigest()
print("MD5:", time.time() - start)

start = time.time()
for _ in range(100000):
    hashlib.sha256(password).hexdigest()
print("SHA-256:", time.time() - start)

start = time.time()
bcrypt.hashpw(password, bcrypt.gensalt())
print("bcrypt hash בודד:", time.time() - start)

התוצאה מדברת בעד עצמה - MD5 ו-SHA-256 מחשבים מאות אלפי hashes בשנייה בקלות, בעוד ש-bcrypt נבנה בכוונה כדי להיות איטי, לפעמים כמה עשיריות שנייה לחישוב בודד.

למה מהירות היא בעיה, לא יתרון

כאן נמצא הלב של הפרויקט. אלגוריתמים כמו MD5 ו-SHA-256 נבנו למטרות שבהן מהירות היא יתרון - בדיקת שלמות קבצים, חתימות דיגיטליות, מבני נתונים. אבל בדיוק המהירות הזאת הופכת אותם למסוכנים לסיסמאות. תוקף שגנב מסד נתונים עם סיסמאות שעברו MD5 יכול לנסות מיליארדי סיסמאות אפשריות בשנייה על חומרה רגילה, ולפצח אחוז גדול מהן תוך שעות בלבד. bcrypt (וגם אלגוריתמים דומים כמו scrypt ו-Argon2) נבנו במכוון כדי להיות איטיים ו"יקרים" מבחינת חישוב, כך שגם תוקף עם חומרה חזקה מוגבל למספר ניסיונות קטן בהרבה בכל שנייה.

סאלטינג - השכבה שמונעת קיצורי דרך

הרחבה טבעית לפרויקט היא להראות למה salt (מלח) קריטי גם הוא. בלי salt, שתי סיסמאות זהות ייצרו בדיוק אותו hash, מה שמאפשר לתוקפים להשתמש ב-rainbow tables - טבלאות ענק מוכנות מראש של hashes לסיסמאות נפוצות. עם salt ייחודי לכל משתמש, אותה סיסמה בדיוק תייצר hash שונה לגמרי אצל כל משתמש, וזה הופך טבלאות מוכנות מראש לחסרות תועלת. ספריות כמו bcrypt כבר מטפלות ב-salt אוטומטית, וזו אחת הסיבות שהן עדיפות בענק על הרכבה ידנית עם hashlib.

הרחבה - בדיקת חוזק סיסמה מול מילון

אפשר להעמיק את הפרויקט עוד צעד ולבנות בודק חוזק סיסמה שמריץ רשימת סיסמאות נפוצות (יש רשימות פומביות כמו rockyou) מול פונקציית ה-hash, ומודד כמה זמן היה לוקח לפצח סיסמה נתונה בהתקפת מילון. זה הופך את המושג "סיסמה חלשה" ממשפט מופשט למספר קונקרטי שאפשר לראות במסך.

מה מרוויחים מהפרויקט

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

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

יש לכם שאלה על ההבדל בין האלגוריתמים או רוצים להשוות תוצאות? בואו לדבר על זה בקהילה.

הצטרפו לקהילה בדיסקורד