A nonce הוא ערך ייחודי שנבחר על ידי ישות בפרוטוקול, והוא משמש כדי להגן על אותה ישות מפני התקפות שנמצאות תחת המטריה הגדולה מאוד של "הפעלה חוזרת".
לדוגמה, שקול פרוטוקול אימות מבוסס סיסמה אשר הולך כך:
- השרת שולח "אתגר" (ערך אקראי כביכול c ) אל לקוח
- לקוח יגיב על ידי שליחת h (c || p) כאשר h היא פונקציית hash מאובטחת (למשל SHA-256), p היא סיסמת המשתמש, ו- ' || ' מציין שרשור
- השרת מחפש את הסיסמה במסד הנתונים שלו, מחשב מחדש את תגובת הלקוח הצפוי ורואה אם זה תואם את מה שהלקוח שלח
סיסמאות הן ערכים סודיים שמתאימים למוח האנושי; ככאלה, הם לא יכולים להיות מורכבים מאוד, ואפשר לבנות מילון גדול שיכיל את סיסמת המשתמש בהסתברות גבוהה. על ידי "גדול" אני מתכוון "ניתן למנות בעזרת אשכול בקנה מידה בינוני בעוד כמה שבועות". לדיון הנוכחי אנו מקבלים מכך שתוקף יוכל לשבור סיסמה אחת על ידי השקעת מספר שבועות של חישוב; זוהי רמת האבטחה שאנו רוצים להשיג.
דמיין תוקף פסיבי: התוקף מצותת אך אינו משנה את ההודעות. הוא רואה את c ו- h (c || p) ולכן הוא יכול להשתמש באשכול שלו כדי למנות סיסמאות פוטנציאליות עד למציאת התאמה. זה יהיה יקר עבורו. אם התוקף רוצה לתקוף שתי סיסמאות אז עליו לבצע את העבודה פעמיים . התוקף רוצה ש יהיה חלוקת עלויות מעט בין שני מופעי ההתקפה, תוך שימוש ב טבלאות מחושבות מראש ("טבלאות קשת" הן רק סוג של טבלה מחושבת מראש עם אחסון מותאם; אך בניית שולחן קשת עדיין מחייבת ספירת המילון המלא וחשיבת כל סיסמא). עם זאת, האתגר האקראי מביס את התוקף: מכיוון שכל מופע כרוך באתגר חדש, קלט פונקציית החשיש יהיה שונה בכל הפעלה, גם אם משתמשים באותה סיסמה. לפיכך, התוקף אינו יכול לבנות שולחנות שימושיים מחושבים מראש, בפרט שולחנות קשת.
כעת נניח שהתוקף יהפוך פעיל. במקום פשוט להתבונן בהודעות, הוא ישנה באופן פעיל הודעות, ישליך כמה, ישכפל אחרים או יכניס הודעות משלו. התוקף יכול כעת ליירט ניסיון חיבור מצד הלקוח. התוקף בוחר ושולח אתגר משלו ( c ') ומחכה לתגובת הלקוח ( h (c' || p) ). שים לב כי אין ליצור קשר עם השרת האמיתי; התוקף פשוט מפיל את החיבור בפתאומיות מיד לאחר תגובת הלקוח, כדי לדמות שגיאת רשת שפירה. במודל התקפה זה, התוקף ביצע שיפור גדול: עדיין יש לו אתגר c ' והתגובה המקבילה, אך האתגר הוא ערך שהתוקף בחר כראות עיניו. מה שהתוקף יעשה זה תמיד לשרת את אותו אתגר c '. שימוש באותו אתגר בכל פעם מאפשר לתוקף לבצע חישובים מוקדמים: הוא יכול לבנות טבלאות מחושבות מראש (כלומר שולחנות קשת) המשתמשות ב"אתגר "המיוחד הזה. כעת התוקף יכול לתקוף מספר סיסמאות נפרדות מבלי לחייב את עלות ספירת המילון עבור כל אחת.
nonce client נמנע מבעיה זו. הפרוטוקול הופך להיות:
- השרת שולח אתגר אקראי c
- הלקוח בוחר n (לא צריך להיות שונה) בכל פעם)
- הלקוח שולח את n || h (c || n || p)
- שרת מחשב מחדש h (c || n || p) (באמצעות ה p em ממסד הנתונים שלו) ורואה אם ערך זה תואם את מה שהלקוח שלח
מכיוון שהלקוח כולל ערך אקראי חדש ("nonce") בקלט פונקציית hash לכל הפעלה, קלט פונקציית hash יהיה שונה בכל פעם, גם אם התוקף יכול לבחור את האתגר. זה מנצח טבלאות מחושבות מראש (קשת) ומשקם את רמת האבטחה המיועדת שלנו.
הדמייה גסה של nonce ייחודי הוא שם המשתמש. לשני משתמשים נפרדים באותה מערכת יהיו שמות נפרדים. עם זאת, המשתמש ישמור על שמו כאשר הוא ישנה את סיסמתו; ושני משתמשים נפרדים עשויים להיות בעלי אותו שם בשתי מערכות שונות (למשל, לכל מערכת דמוית Unix יש משתמש "שורש"). אז שם המשתמש אינו נונסקה טובה (אך עדיין עדיף על כך שאין לו בכלל נונסון של לקוח).
לסיכום, הלקוח nonce עוסק בהגנה על הלקוח מפני התקפת שידור חוזר (" שרת "להיות למעשה תוקף, שישלח את אותו אתגר לכל לקוח שהוא רוצה לתקוף). אין צורך בכך אם האתגר מבוצע בערוץ הכולל אימות שרתים חזק (כגון SSL). חילופי מפתח מאומת סיסמאות הם פרוטוקולים מתקדמים המבטיחים אימות הדדי מבוסס סיסמא בין לקוח לשרת, מבלי להזדקק לאמון מוקדם יותר ("אישורי הבסיס" כאשר לקוח SSL מאמת את אישור שרת ה- SSL) והגנה נגד תוקפים פעילים ופסיביים (כולל התקפת "אשכול לשבועיים" על סיסמה אחת, כך שזה טוב יותר מהפרוטוקול לעיל, nonce או no nonce).