בונים כלי משלכם לבדיקת סיסמאות - ולומדים למה רוב הסיסמאות שלכם חלשות¶
כמעט כל אחד שמתחיל בתחום אבטחת המידע שמע פעם את המשפט "תבחרו סיסמה חזקה", בלי שאף אחד באמת הסביר מה זה אומר מעבר ל"תוסיפו תו מיוחד". הדרך הכי טובה להבין את זה לעומק היא לבנות כלי משלכם שבודק חוזק סיסמאות. זה פרויקט קצר, אבל הוא חושף בדיוק את ההיגיון שעומד מאחורי כל מדיניות סיסמאות שראיתם אי פעם.
מה בכלל הופך סיסמה לחלשה¶
יש כמה גורמים שמשפיעים על חוזק סיסמה, וכדאי להפריד ביניהם כי אנשים נוטים לערבב אותם. אורך הוא הגורם הכי משמעותי - סיסמה ארוכה עם תווים פשוטים לרוב חזקה יותר מסיסמה קצרה עם תווים "מורכבים". מורכבות, כלומר שילוב של אותיות גדולות, קטנות, ספרות וסימנים, מוסיפה חוזק אבל פחות ממה שאנשים חושבים. והגורם השלישי, שהכי הרבה אנשים מתעלמים ממנו, הוא נפוצות - האם הסיסמה הזאת כבר מופיעה ברשימות של סיסמאות שדלפו בעבר.
סיסמה כמו P@ssw0rd1 נראית "מורכבת" לפי כל כלל טכני - יש בה אותיות גדולות, קטנות, ספרה וסימן. אבל היא חלשה מאוד, כי היא נמצאת כמעט בראש כל רשימת סיסמאות נפוצות שקיימת. לעומת זאת, משפט אקראי כמו סוסתולעפילזז (בדוגמה אנגלית - ארבע מילים אקראיות מחוברות) יכול להיות הרבה יותר חזק, גם בלי סימנים מיוחדים, פשוט כי הוא ארוך ולא צפוי.
מושג האנטרופיה בקצרה¶
אנטרופיה, במונחי אבטחת מידע, היא בעצם מדד לכמה ניחושים בממוצע יידרשו לתוקף כדי לפגוע בסיסמה. ככל שיש יותר אפשרויות לכל תו וככל שהסיסמה ארוכה יותר, האנטרופיה עולה, וזה הופך תקיפת brute force לפחות ריאלית מבחינת זמן. סיסמה עם אנטרופיה נמוכה, גם אם היא "נראית" מסובכת לעין, יכולה להישבר במהירות אם היא חוזרת על דפוסים מוכרים.
בפועל, לצורך הפרויקט, אפשר לחשב הערכה גסה של אנטרופיה עם נוסחה פשוטה - גודל מרחב התווים בחזקת אורך הסיסמה, ואז לוקחים לוג בבסיס 2 כדי לקבל מספר בביטים:
import math
def estimate_entropy(password):
charset = 0
if any(c.islower() for c in password): charset += 26
if any(c.isupper() for c in password): charset += 26
if any(c.isdigit() for c in password): charset += 10
if any(not c.isalnum() for c in password): charset += 32
return len(password) * math.log2(charset) if charset else 0
זה חישוב מקורב בלבד, לא מדויק מבחינה מתמטית טהורה, אבל הוא מספיק כדי לתת ציון יחסי ולהראות בבירור למה סיסמאות ארוכות מנצחות סיסמאות "מורכבות אבל קצרות".
בדיקה מול רשימת סיסמאות נפוצות¶
החלק השני של הכלי הוא הכי חשוב בפועל, ומדגים למה חישוב אנטרופיה לבד לא מספיק. תורידו רשימת סיסמאות נפוצות חינמית וידועה, כמו rockyou.txt, שמשמשת בקהילת האבטחה בדיוק למטרות לימוד כאלה, ותבדקו האם הסיסמה שהמשתמש הזין מופיעה שם:
def is_common(password, wordlist_path="rockyou.txt"):
with open(wordlist_path, encoding="latin-1") as f:
common = set(line.strip() for line in f)
return password in common
בגרסה אמיתית כדאי לטעון את הרשימה פעם אחת לזיכרון ולא בכל קריאה, אבל הרעיון ברור - גם סיסמה עם ציון אנטרופיה גבוה נחשבת חלשה אם היא כבר מוכרת לתוקפים.
הרחבה - סימולציית dictionary attack על האש שלכם¶
לצורך למידה בלבד, ועל נתונים שיצרתם בעצמכם, אפשר להרחיב את הפרויקט ולהראות איך תוקף בפועל שובר סיסמה מגובבת (hashed). לוקחים סיסמה, מחשבים לה hash עם hashlib, ואז מריצים לולאה שמנסה לחשב hash לכל מילה ברשימת מילים ולהשוות לתוצאה. ברגע שיש התאמה, מצאתם את הסיסמה המקורית. זה בדיוק העיקרון שמאחורי כלים כמו hashcat או John the Ripper, רק בגרסה מוקטנת שאתם כתבתם וממש מבינים.
חשוב להדגיש - התרגול הזה נעשה רק מול hash שיצרתם בעצמכם על סיסמת בדיקה, לא מול נתונים אמיתיים של אף אחד אחר.
מה זה מלמד אתכם בפועל¶
אחרי שבניתם כלי כזה, אתם כבר לא סתם ממליצים למישהו "תוסיף תו מיוחד" בלי הבנה. אתם יודעים להסביר למה, ולדעת גם להעריך מדיניות סיסמאות של ארגון ולזהות אם היא בנויה נכון או רק "נראית" מחמירה. זו בדיוק סוג החשיבה שמייחד בודק אבטחה שמבין את היסודות מבודק שרק מריץ כלים.
מי שרוצה להמשיך משם לתחום בדיקות החדירות בצורה מסודרת, כולל תקיפת סיסמאות אמיתית בסביבת מעבדה, קורס בודק החדירות שלי בעברית מכסה את זה לעומק.
לסיכום¶
כלי לבדיקת חוזק סיסמאות הוא פרויקט קצר שמחבר בין תכנות בסיסי לבין הבנה אמיתית של אבטחת מידע. במקום לזכור כללים בעל פה, אתם כותבים אותם בקוד, ובתהליך מבינים בדיוק למה הם נכונים, ואיפה הם נכשלים.