מדוע קודי TOTP נכשלים כשהשעון של המכשיר סוטה
הקוד הוא גיבוב של הסוד ושל שלב הזמן הנוכחי. השוו את ההיסטים בשני הקצוות, ואז תקנו את השעון במקום להרחיב את החלון.
קודים חד-פעמיים יכולים להיות נכונים לחלוטין בטלפון שלכם ובכל זאת להידחות על ידי השרת באותה השנייה. שני הצדדים מחשבים את אותה פונקציה מסוד משותף ומשלב הזמן הנוכחי, ולכן אי-הסכמה לגבי הזמן יוצרת אי-הסכמה לגבי הקוד. זה הופך את סטיית השעון לתקלה בעלת משמעות אבטחתית ולא רק להטרדה.
שני שעונים חשובים כאן, ותיקון הנראה לעין הוא החלק שאנשים עושים ראשון. זה שבדרך כלל זקוק לתשומת לב הוא האחר.
הקוד הוא פונקציה של הזמן, לא סיסמה
TOTP לוקח את הסוד המשותף ומונה הנגזר מהזמן הנוכחי, מעביר את שניהם דרך גיבוב עם מפתח ומקצר את התוצאה למחרוזת עשרונית קצרה, כפי שמפורט ב-RFC 6238. המונה מתקדם בכל שלב זמן, בדרך כלל שלושים שניות, כך שאותו סוד מפיק ערך חדש כשהשלב משתנה. המאמת מחשב מחדש את הערך הצפוי עבור השלב הנוכחי ומשווה, מה שדורש את אותו סוד ואת אותה תפיסה של עכשיו. סיסמה נשארת לשימוש חוזר עד שהיא מוחלפת, בעוד שערך זה פג בגדר שהלקוח אינו רואה.
לכן קוד אחד עובד והבא אחריו נכשל רגעים לאחר מכן. זה גם מסביר מדוע העתקת קוד מהודעת צ’אט היא הרגל כה בלתי אמין.
שני שעונים חייבים להסכים, לא אחד
חומר ההרשמה הוא הדבר המשותף הראשון, והזמן הוא השני. אם הסוד נכון בעוד השעונים שונים ביותר מהחלון המותר, כל ערך שנוצר נופל בשלב הלא נכון ונפסל. אם השעונים מסכימים בעוד הסוד שגוי, גם כל ערך נפסל, ו-שני הכשלים נראים זהים ממסך הכניסה. הפרדתם פירושה בדיקת רשומת החשבון והזמן בנפרד, בסדר הזה.
השעון של המאמת ראוי לאותה בחינה כמו זה של המכשיר. שרת שמקור הזמן שלו שבור פוסל קודים נכונים מכל המשתמשים בבת אחת, והדוחות יתארו הפסקה פתאומית ולא סטייה. כדאי להכיר את הדפוס הזה, כי התיקון שלו שייך לשרת ולא למאה טלפונים.
מה עולה להרחיב את החלון
מימושים עשויים לקבל קוד משלב סמוך כדי לבלוע הבדלים קטנים, וסובלנות זו היא החלטת תכנון ולא התאמה חינם. כל שלב נוסף מכפיל את מספר הערכים התקפים בכל רגע, וזה בדיוק מה שתוקף שמנחש מעדיף. כלל מניעת החזרה חשוב מאותה סיבה, כי קוד שמתקבל פעמיים הוא קוד שדלף בצורה שימושית. מנהל שמרחיב את החלון כדי להשתיק תלונות מחליף תכונה אמיתית בשיפור קוסמטי.
תיקון השעון הוא התיקון, בעוד שהרחבת החלון היא סם הרגעה. הראשון מסיר את הסיבה והשני מסתיר אותה.
בדקו את שני השעונים לפני שתנסו שוב
קראו את הזמן במכשיר ובשרת, והשוו את ההיסטים ולא את הזמנים המקומיים המוצגים. הפקודות שלהלן מציגות את מצב הסנכרון ואת רגע ה-UTC הגולמי במארח או בשרת לינוקס. הריצו אותן בשני הקצוות לפני שתשנו הגדרת אימות כלשהי.
timedatectl
date -u +'%Y-%m-%dT%H:%M:%SZ'
chronyc tracking
timedatectl timesync-status
היסט שנמדד בשניות אינו מזיק, היסט שנמדד בדקות מסביר דחייה, ומערכת שאינה מדווחת על מקור סנכרון כלשהו היא מועמדת לשניהם. השוו את שתי חותמות הזמן של UTC ישירות, כי הזמן המקומי כולל אזור זמן שהאלגוריתם אינו רואה לעולם. אם ההיסטים קטנים והקודים עדיין נכשלים, הפסיקו לכוון שעונים ובמקום זאת בחנו את רשומת ההרשמה. ניסיונות חוזרים מול חשבון נעול הופכים את התקלה המקורית לקשה יותר לצפייה.
רשמו את זמן הדחייה, את ההיסט ואת טקסט השגיאה, והשאירו את הסוד המשותף מחוץ לכך. התמיכה יכולה לעבוד עם השלושה הראשונים ולעולם לא אמורה לראות את הרביעי.