איך לשמור סיסמה בדטהבייס ולזהות משתמש

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

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

בקצרה:

  1. את הסיסמאות יש לשמור בדטהבייס לאחר שעברו ערבול חזק מבוסס PBKDF (Password Based Key Derivation Function), מלח אקראי חזק, והגדרות ערבול חזקות.
  2. מומלץ, אך לא חובה, להצפין את הסיסמה.
  3. בתהליך האימות, בדיקת הסיסמה צריכה להיעשות על כל המחרוזת, מה שנקרא "בדיקה איטית", ולא רק עד הטעות הראשונה.
  4. בתהליך האימות, אם המשתמש לא קיים – יש לדמות כאילו המשתמש קיים והסיסמה לא נכונה.
  5. אפשרי, אך לא חובה, לעשות מספר בדיקות נוספות על הסיסמה אשר לא פוגעות באבטחה, כדי לבדוק טעויות נפוצות בסיסמה (למשל המשתמש בטעות הקליד עם Caps Lock או שנמצא במקלדת עברית במקום אנגלית).

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

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

היום יותר ויותר מערכות מאפשרות הזדהות אחידה – ביצוע ההזדהות דרך מערכת אחרת שכבר יש למשתמש, למשל Google (לכל מי שיש ג'ימייל למשל) או Microsoft Live. זה כמובן קל ונוח – מוריד את האחריות של ההזדהות ואפילו מחזק את האבטחה של המשתמשים, אבל לא תמיד זה אפשרי, ולכן נסביר על כל התהליך של ההזדהות במדריך הזה.

התקפות אוף-ליין (Offline)

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

נניח ואת הסיסמה שהמשתמש הגדיר אנחנו שומרים כמו שהיא, מה שנקרא בשפה המקצועית האבטחתית Cleartext (כלומר טקסט נקי), אז ברגע שהתוקף השיג גישה למסד הנתונים – יש לו מיידית את הסיסמאות של כל המשתמשים וללא שום מאמץ. אפשר גם לזכור שרוב המשתמשים משתמשים באותה הסיסמה ליותר ממערכת אחת, ולכן המשתמש יכול לנסות לפרוץ לכתובות המייל עם הסיסמה הרשומה וכנראה להצליח בכמה כאלה.

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

פונקציית גיבוב קריפטוגרפית

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

לפונקציות גיבוב קריפטוגרפיות יש 3 מאפיינים עיקריים ומיוחדים:

  1. קושי בהיפוך – נניח ויש לנו ערך החזר (פלט) שיצא מתוך פונקציית גיבוב כזאת, יהיה לנו מאוד קשה למצוא איזה ערך מקורי (קלט) הביא לפלט הזה. סביר להניח שנצטרך לעבור על כל הערכים בעולם, להריץ עליהם את הערבול ואז לבדוק האם הפלט שלהם יהיה זהה לערך שמצאנו.
  2. קושי במציאת מקור נוסף – נניח ויש לנו ערך לקלט, יהיה מאוד קשה למצוא ערך קלט אחר (שונה מהערך קלט הראשון), שהפעלת הערבול על שני הקלטים השונים האלה יביא לאותה תוצאה (פלט).
  3. קושי במציאת התנגשויות – יהיה קשה מאוד למצוא 2 ערכי קלט שונים שהפעלת הערבול על שניהם תביא לאותה התוצאה (פלט). ההבדל מההגדרה הקודמת – בהגדרה הקודמת נתון קלט וצריך למצוא קלט אחר שיביא לאותו הפלט, בעוד שבהגדרה הזאת מדובר על למצוא 2 קלטים שונים (לא כאלה שניתנו לנו) שיביאו לתוצאה זהה.

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

md5("Hello World!") = 48656c6c6f20576f726c6421

בצורה זה, ניתן לערבל את הסיסמה של המשתמש ולשמור את הערבול. כדי לזהות את המשתמש – יש לקחת את הסיסמה שהמשתמש הקליד, לערבל אותה, ואז להשוות את הערבול של המשתמש כעת למול מה שקיים במערכת.

פשוט, לא?

אז כן, פשוט. פשוט מדי. כבר לפני מספר שנים נמצאה פרצה ב-md5, ובתוספת העובדה שהפלט שלה קצר (יחסית), גורם לכך שיש חשש כבד יותר להתנגשויות והיא הוגדרה כ"לא בטוחה", ולכן לא רצוי להשתמש בה לנושאי אבטחה בכלל. גם פונקציית SHA-1 אשר מחזירה ערך בגודל 160 סיביות לא בטוחה מהסיבות האלה, ולכן רצוי להשתמש לכל הפחות ב-SHA-256 אשר מחזירה ערך בגודל 256 סיביות אבל מומלץ אפילו יותר להשתמש ב-SHA-512 שמחזירה ערך בגודל 512 סיביות.

כעת, אם לתוקף יש את מסד הנתונים עם הסיסמאות מעורבלות – הוא יצטרך להשקיע מאמצים גדולים (יחסית) כדי למצוא ערך כלשהו (לאו דווקא הסיסמה המקורית!) שיתאים לתוצאת הערבול של משתמש מסוים – כל זאת כדי שיוכל לפרוץ לו.

אבל שימו לב, במקרה הזה – אם יש 2 משתמשים עם אותה הסיסמה – יהיה להם את אותו הערך בשדה של הסיסמה לאחר הערבול. כלומר במידה והתוקף שלנו הצליח למצוא את הקלט המתאים כדי לפרוץ למשתמש X כלשהו, כל המשתמשים בעלי אותה הסיסמה גם כן נפרצו באותו הרגע! וזה גם אומר עוד משהו – בהינתן מספיק זמן, ניתן ליצור טבלה ענקית (מאוד… מאוד ענקית) של קלט-פלט לכל פונקציה כזאת, וככה כל מה שנדרש מהתוקף הוא להשוות בטבלה הזאת. זה כבר נהיה לו פשוט מספיק, לא? אז מסתבר שכבר עשו כזה.

טבלאות קשת (Rainbow tables)

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

נוסיף קצת מלח (Salt)

כדי להלחם בטבלאות הקשת האלה ניתן להוסיף מלח (כן, ככה קוראים לזה בעגה המקצועית). מלח הינו אוסף תווים אקראי מאוד שמפיקים בכל פעם שמגדירים סיסמה. אורך המלח צריך להיות לפחות 8 בתים (bytes) אך מומלץ אפילו 16 בתים, אין צורך ביותר. כאשר מערבלים את הסיסמה – נוסיף את המלח, ואת המלח נשמור לצד תוצאת הערבול במסד הנתונים (בין אם בהפרדה מיוחדת או בעמודה נפרדת).

נניח שהמלח שלי זה "abcdwxyz" והסיסמה שלי זה "P@ssw0rd1", אז אפשר להגדיר שכל פעם שאנחנו מפעילים את הערבול (גם בעת שמירת הסיסמה וגם בעת אימות המשתמש), נערבל את הערך הזה: "abcdwxyz:P@ssw0rd1", כלומר את המלח בתוספת נקודתיים ואז הסיסמה. זה כמובן דוגמה ואפשר לעשות זאת בצורות שונות אבל הכוונה היא שהצורה שאתם בוחרים תהיה זהה תמיד. כמו כן יש פונקציות ערבול שמקבלות את המלח בנפרד (לדוגמה HMAC-SHA-256 או HMAC-SHA-512) ככה שלא תצטרכו להגדיר בעצמכם.

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

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

התקפת מילון (Dictionary Attack)

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

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

בשביל למנוע מצב של תקיפה כזאת חשוב להגדיר 2 דברים:

  1. מדיניות סיסמאות – חשוב שתהיה מדיניות סיסמאות ברורה וחזקה לכל המשתמשים, למשל – לפחות 8 תווים, שתכיל אותיות קטנות וגדולות, שתכיל מספרים ורצוי גם שתכיל תווים מיוחדים (למשל רווח, סימנים כמו @ # $ % …). בכללי כמובן רצוי לאפשר את למשתמש להכניס כל תו. כמו כן – אפשר להגדיר שאורך הסיסמה יהיה עד אורך הגיוני כלשהו נניח 64 תווים – זאת מתוך ההנחה שסיסמאות מאוד ארוכות הינן סיסמאות שמועתקות ממקום ידוע (למשל פסקה מתוך ספר ידוע) מה שגורם לסיסמה להיות ידועה וחלשה.
  2. להאט את זמן החישוב – ניתן להגדיר תהליך ערבול סיסמה כך שיהיה מעט יותר איטי. במידה והערבול איטי מספיק, אבל לא איטי מדי בשביל התחברות של משתמש – אז למעשה התחברות לגיטימית של משתמש תיקח זמן סביר, בעוד שלנסות לחשב טבלת קשת, גם של מילים מוכרות, תיקח זמן בלתי סביר.

נסביר את שתי הנקודות האלה.

מדיניות סיסמאות

בואו נניח לרגע שהתוקף משתמש בשיטת Brute-Force כדי לפרוץ את הסיסמה ומדיניות הסיסמאות שלנו מאפשרת כל סיסמה שגדולה מ-6 תווים. אז התוקף שלנו יתחיל למשל מהסיסמה "000000", יערבל ויבדוק. ימשיך לסיסמה "000001" יערבל ויבדוק, וכן הלאה…

עכשיו נניח לצורך הדוגמה שערבול לוקח 1 מיקרו-שניה. אם הסיסמה מכילה רק מספרים – אז הוא נדרש לעבור על 10 בחזקת 6 אפשרויות (כל המספרים באורך 6 תווים) ועוד 10 בחזקת 7 אפשרויות (כל המספרים באורך 7 תווים) ועוד 10 בחזקת 8 אפשרויות (כל המספרים באורך 8 תווים) (וסביר להניח שלא יותר, משתמשים סטנדרטיים לא נוטים להגדיר סיסמה ארוכה יותר מדי ממה שהמדיניות מאפשרת). כלומר בערך 111,000,000 חישובים לבצע, כאשר כל חישוב לוקח 1 מיקרו-שניה ייקח לתוקף 111 שניות, כלומר קצת פחות מ-2 דקות לחשב את כל הסיסמאות האפשריות. בהחלט זמן סביר. וכמו שאמרנו – בפועל עם התקפת מילון זה ייקח אפילו הרבה פחות.

בואו נניח עכשיו שאנחנו מגדירים מינימום של 8 תווים, מחייבים תווים גדולים וקטנים וגם מספרים, אבל ללא סימנים מיוחדים. אז נדרש לעבור על 10 בחזקת (8 ועוד 26 ועוד 26) אפשרויות (כל המספרים, התווים הקטנים והתווים הגדולים באורך 8 תווים). זה כבר נהיה מספר גדול מדי לרשום, אבל כנראה שייקח מספר שעות לפרוץ את הסיסמה הזאת ב-Brute-Force, וכנראה פחות עם התקפת מילון.

אם נוסיף גם תווים מיוחדים? אז זה יהיה 10 בחזקת (8 ועוד 26 ועוד 26 ועוד 10 של התווים המיוחדים) – אתם כבר מבינים לאיפה זה הולך. במקרה הזה יכול לקחת מספר ימים מצומצם לכל סיסמה.

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

האטה של זמן החישוב

וכאן נכנס לתמונה מושג בשם Password-Based Key Derivation Function (או PBKDF לקיצור). פונקציה זו, בגדול, לוקחת את המלח שעשינו, מצמידה לסיסמה ומריצה ערבול (ממש כמו מקודם), ואז עושה את זה שוב – לוקחת את המלח, מצמידה לתוצאת הערבול ומריצה עוד פעם את הערבול, ככה שוב ושוב כמספר הפעמים שנגדיר (כמו שאמרנו – בגדול, יש המון גישות וצורת לבצע את זה).

מה יצא לנו? אם פעולת ערבול רגילה לוקחת 1 מיקרו-שניה, אז עכשיו כדי לבצע את חישוב כל סיסמה נצטרך לבצע לכל הפחות 100,000 ערבולים ולכן לכל חישוב סיסמה ייקח זמן של עשירית שניה! זה כבר נהיה מורכב הרבה יותר! לעומת זאת, היום יש מכונות מאוד חזקות, ובשילוב כרטיסים גרפיים שיודעים לבצע חישובים מורכבים במכה – יש מכונות שיכולות לבצע 200,000 ערבולים כאלה במכה ואפילו יותר. לכן חשוב שההגדרות של ה-PBKDF יהיו חזקות דיין, שהסיסמה תהיה מורכבת והמלח יהיה באורך סביר ואקראי מספיק. חלק מה-PBKDFים יכולים גם לבטל את היעילות של כרטיסים גרפיים קליל.

הגדרות נכונות ויעילות יכולות לגרום לזמן חישוב של מספר ימים לכל הפחות (כמובן שבמידה והמשתמש השתמש במילים מאוד מוכרות אז התקפת מילון תגיע ליעד די מהר), וזה כבר זמן מאוד סביר לתפוס את הפרצה, להודיע למשתמש ולאפס לכולם את הסיסמאות. חשוב לזכור, כוח העיבוד העולמי והנגיש לכל תוקף גדל כל הזמן, ולכן ייתכן שכל מספר שנים תצטרכו לבחון שוב את ההגדרות ולחזק אותן, למשל במקום 100 אלף פעמים (איטרציות) שהיה נכון בעבר – כיום רצוי לפחות 200 אלף – וכד'.

ישנן מספר פונקציות PBKDF מוכרות, חשוב לחפש ולהבין מה ההגדרות המתאימות והחזקות לכל פונקציה. מבין המוכרות תוכלו למצוא את:

  1. Argon2id – זוכת תחרות ערבול הסיסמאות של שנת 2015.
  2. scrypt – ערבול חזק, ידוע וותיק שנפוץ בעיקר בסביבת לינוקס.
  3. PBKDF2 – מומלץ על-ידי גוף NIST שהוא ארגון הסטנדרטים הטכנולוגיים של ארה"ב ועומד בתקן FIPS-140 שלהם. גופים שנדרשים לעמוד בתקן יצטרכו להשתמש בו, ואת הדוגמה שלנו נעשה עליו כיוון שהוא קל ונגיד לכתיבה בסי שארפ.

נוסיף קצת פלפל (Peppering)

פלפל מוסיף עוד שכבה של הגנה על הסיסמאות, אבל הוא לא יכול לבוא לבד, הוא חייב לבוא מעל כל תהליך הערבול עליו דיברנו.

פלפל למעשה הוא הצפנה של כל הסיסמאות בעזרת פונקציית הצפנה ומפתח משותף. את המפתח אסור לשמור במסד נתונים.

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

את מפתח ההצפנה יש לשמור במקום שמשותף לכל השירותים שבודקים את הסיסמה – אבל הוא חייב להיות מאובטח. למשל הוא יכול להיות במכשיר פיזי מאובטח (token) שמשותף לכל המכונות, או למשל ב-AWS Secrets שהינו שירות של אמזון לשמירת "סודות" כגון מפתחות. אסור לשמור את המפתח במסד הנתונים כיוון שכל המטרה הינו להגן על הצפנת הסיסמאות במסד הנתונים, כך שאם תוקף הצליח למצוא את מסד הנתונים – ייקח לו אפילו עוד זמן עד שיצליח להבין ולפרוץ את המפתח המאובטח.

יש גם לנהל מדיניות של החלפת מפתחות ההצפנה – למשל אחת לשנה, ואז להחליף את כל ההצפנה של כל הסיסמאות.

בואו נדבר פרקטיקה

אז איך מבצעים את זה בפועל? אנחנו נראה דוגמה של שימוש ב-PBKDF2 על סיסמה שהגיעה ממשתמש.

התקפת זמן (Time attack)

בואו נדבר על נושא קצת יותר מורכב – איך מתבצעת בדיקת הסיסמה.

נניח ויש לנו 2 מחרוזות "שלום1" (בתוך משתנה h1) ו"שלום2" (בתוך משתנה h2), כאשר אנחנו עושים השואה (נניח h1 == h2) אז מה שקורה מאחורי הקלעים, ממש בליבה של המעבד – שעוברים על כל תו ואז בודקים אם הוא שווה. "ש" שווה ל-"ש"? אם כן, אז תמשיך לתו הבא, "ל" שווה ל-"ל"? אם כן אז תמשיך לתו הבא…. "1" שווה ל-"2"? לא? אז תחזיר תוצאה שלילית (false).

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

למה זה רע? נניח של בדיקה של תו לוקחת X זמן (נניח לצורך הפשטות 1 מיקרו-שניה) ואנחנו מנסים למצוא את הערך של מחרוזת סודית h1 (נניח שהיא "שלום"), אז אנחנו נשלח לפונקציית הבדיקה את הערך "אאאא" – לקח 1 מיקרו-שניה? סימן שהתו הראשון הוא לא "א". נשלח את "באאא", לקח 1 מיקרו-שניה? סימן שהתו הראשון הוא גם לא "ב". כך נמשיך עד שנגיע ל "שאאא", ופה כבר לוקח לנו 2 מיקרו-שניה! הנה מצאנו! התו הראשון הוא "ש"! ככה אפשר להמשיך עד שנמצא את כל התווים הנכונים ונקבל תוצאה נכונה! (כמובן שמבחינה מעשית זה קצת יותר מורכב בגלל סטיות של זמן עיבוד, אבל בהרצה של מספיק פעמים – הפרש זמן הממוצע בין בדיקה נכונה ללא נכונה הוא שונה, ולכן מאוד חשוב להתחשב בסוג זו של התקפה).

אז איך פותרים את זה ומונעים את ההתקפה? האמת די פשוט – צריך לגרום לכך שכאשר בודקים בין 2 מחרוזות – תמיד בודקים את כל המחרוזת. אפשר ליצור פונקציית עזר שמבצעת את זה דיי בקלות. נוסיף את SlowEquals ונתקן את ComparePassword:

בדיקה של טעויות נפוצות בסיסמה

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

חשוב להגדיר במדויק מה ה"טעויות" שייבדוק, וכל בדיקה היא חייבת להיות מדוייקת וסגורה, כי רק ככה האבטחה נשמרת באותה מידה. זה בא מתוך ההנחה שאם הבדיקות מדוייקות – אז סיבוכיות האבטחה של הסיסמה הנכונה, וסיבוכיות האבטחה של בדיקה של מספר קבוע של טעויות (נניח 5) יהיה זהה, או במילים קצת יותר מתמטיות – סיבוכיות האבטחה של סיסמה נכונה הוא O(1) וסיבוכיות האבטחה של בדיקת של הסיסמה ועוד 5 טעויות הינו O(1 + 5) אבל בגלל שמדובר על סיבוכיות וקובעים אז זה שווה ל-O(1).

טעויות נפוצות שאנחנו נגדיר:

  1. שימוש ב-Caps-Lock. שימו לב! זה לא אומר לבדוק את הסיסמה כאשר כל התווים קטנים או כולם גדולים, אלא היפוך של כל תו גדול לקטן וכל תו קטן לגדול. זה הגדרה מדוייקת כיוון שיש רק תוצאה אחת שיכולה להתבצע מהטעות הזאת, ולא אינספור כאלה.
  2. הוספת תו בודד בהתחלה – לפעמים למשתמשים מחליקה האצבע ונוסף להם תו בודד בהתחלה, נבדוק האם הסיסמה זהה לקלט פחות התו הראשון.
  3. הוספת תו בודד בסוף – אותו הדבר כמו הסעיף הקודם רק עם התו האחרון.
  4. התו הראשון הינו תו גדול – במכשירים ניידים יש מצבים שבהם המקלדת הופכת את התו הראשון לתו גדול. במקרה כזה אפשר לבדוק האם התו הראשון גדול – אם כן אז להקטין רק אותו ואז לבדוק את הסיסמה.
  5. במידה והמשתמשים שלנו רק מישראל – אפשר להוסיף בדיקה של שימוש במקלדת עברית (בדומה לשימוש ב-Caps-Lock). את זה ספציפית לא נדגים.

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

נתקן את הפונקציה שבודקת לנו את הסיסמה כך שתיראה כך:

מדיניות החלפת סיסמאות

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

כמו כן, וזו הנקודה העיקרית – החלפה תדירה של סיסמאות מכריחה את המשתמש למצוא דרכים יצירתיות בשבילו כדי שיזכור את הסיסמה. בסופו של דבר גילו שאנשים עושים שינויים קטנים בסיסמה (למשל אם הסיסמה היתה "סיסמה1" עכשיו תהיה "סיסמה2" וכד'), ואפילו שומרים אותה על פתק נייר ליד המחשב שלהם! בשלב זה הסיסמה חשופה לכל מי שעובר ליד העמדה של המשתמש וכל נושא האבטחה נמחק כאילו לא היה. אגב – וחשוב לשים לב – גם מדיניות סיסמאות חזקה מדי ומורכבת מדי בה תחייבו את המשתמשים בתווים מיוחדים – אולי יגרום לתוקף מהאינטרנט למצוא את הסיסמה, אבל רוב המשתמשים לא יזכרו את הסיסמה וגם אותה יכתבו על פתק או יותר גרוע – ישמרו במסמך על המחשב.

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

הגישה היותר נכונה היום היא שילוב של:

  1. לשלוח הודעה למשתמש בכל פעם שיש שינוי רגיש – כניסה ממכשיר/מחשב חדש, שינוי סיסמה וכד'.
  2. לבחון באופן קבוע האם התקיימה פריצה והמידע נגנב (compromised). במידה וכן – לשלוח מיד הודעה לכל המשתמשים ולהסביר להם את מה שקרה, להפציר בהם לשנות סיסמה, ולהגדיר לכל המשתמשים שהם צריכים לשנות סיסמה ברגע שייכנסו מחדש למערכת.

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

סיכום

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

כתיבת תגובה

האימייל לא יוצג באתר. שדות החובה מסומנים *