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

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

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

כמו פונקציית גיבוב קונבנציונלית הנפוצה ביישומי מחשב לא קריפטוגרפיים, תפקידה העיקרי הוא למפות תחום גדול לטווח קטן, אך הן נבדלות במספר היבטים חשובים. פונקציית גיבוב כללית מקבלת קלט באורך שרירותי ומפיקה פלט באורך קבוע. בניסוח פורמלי עבור התחום <math>D</math> והטווח <math>R</math> תמיד מתקיים <math>h : D\rightarrow R, |D| > |R|</math>. לפי עקרון שובך היונים העובדה שהפונקציה ממפה מקורות רבים לתמונות מעטות משמעה שבהכרח קיימות התנגשויות - שני קלטים שונים שהפונקציה מפיקה מהם פלט זהה. בהנחה שפונקציית הגיבוב רנדומלית, אם <math>t</math> הוא אורך הקלט בסיביות ו-<math>n</math> אורך הגיבוב בסיביות הרי שבמקרה הממוצע <math>2^{t-n}</math> קלטים ימופו באופן זהה. במילים אחרות ההסתברות להתנגשות היא <math> 2^{-n}</math> ללא תלות ב-<math>t</math>.

==תכונות בסיסיות==
השאלה האם קיימת פונקציה חד-כיוונית מוכחת מבחינה מתמטית, נובעת מהשאלה הפתוחה האם P=NP. לאור זאת לא ידוע אם ניתן ליצור פונקציית גיבוב קריפטוגרפית חד-כיוונית 'אמיתית'. עם זאת, קיימות פונקציות הנחשבות כחד-כיווניות לכל צורך מעשי שביטחונן מתואר במונחים של כח המחשוב הדרוש כדי להפוך אותן. מסיבה זו ככל שכח המחשוב עולה, נדרש להחליפן מעת לעת בפונקציות חזקות יותר. פונקציית גיבוב תקרא קריפטוגרפית אם היא מקיימת שלוש תכונות בסיסיות (לפחות את שתי הראשונות), מהקל אל הכבד:
#קושי בהיפוך (preimage resistance); בהינתן פלט מסוים, מציאת הקלט המקורי שלו, קשה מבחינה חישובית. או בניסוח פורמלי, בהינתן פונקציית גיבוב קריפטוגרפית <math>H</math> וערך גיבוב <math>h</math>, מציאת ערך <math>x</math> שעבורו <math>H(x)=h</math>, היא משימה קשה.
#קושי במציאת מקור נוסף (2nd-preimage resistance); בהינתן קלט כלשהו יהיה קשה חישובית למצוא קלט אחר המוביל לאותו פלט, או בניסוח פורמלי, בהינתן <math>x</math>, מציאת <math>x'</math> שעבורו <math>x'\ne x</math> כך שיתקיים <math>h(x)=h(x')</math>, היא משימה קשה.
#קושי במציאת התנגשויות (collision resistance); מציאת שני קלטים שונים כלשהם המפיקים פלט זהה קשה מבחינה חישובית. בניסוח פורמלי מציאת מקורות <math>x,x'</math> עבורם <math>x\neq x'</math> ומתקיים <math>h(x)=h(x')</math> היא משימה קשה. בניגוד לתכונה הקודמת שני הקלטים חופשיים ויכולים להיות כל אחד מהמקורות שישנם בתחום ההגדרה של פונקציית הגיבוב.

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

תיאור סכמת פונקציית גיבוב קריפטוגרפית

פונקציה חד-כיוונית העמידה בפני התנגשויות (הגדרה 3) היא החזקה ביותר והיא אינה הכרחית בכל המקרים. המודל המקובל להגדרת קושי מבחינה חישובית הוא במונחים של סיבוכיות זמן. כלומר פונקציית גיבוב <math>h : X \rightarrow Z</math> נחשבת לחזקה מספיק (לכל צורך מעשי) אם זמן הריצה של האלגוריתם הטוב ביותר שידוע למציאת מקור x לתמונה z (הפיכת הפונקציה <math>h</math>) הוא מסדר גודל של <math>2^{|Z|}</math> (מספר תתי-הקבוצות שישנן ב- <math> Z</math>). להבדיל, זמן הריצה של אלגוריתם למציאת התנגשויות עשוי להיות קצר באופן משמעותי, במקרה גרוע במיוחד עבור המצפין, רק <math>\textstyle 2^{\frac{|Z|}{2}}</math>. זאת בגלל התקפת יום הולדת שמבוססת על פרדוקס יום ההולדת.

===התקפת יום הולדת===
פרדוקס יום ההולדת טוען שהסיכויים שיימצאו בחדר אחד שניים מתוך 23 אנשים שלהם יום הולדת זהה, הם בערך 0.507 (מעל 50 אחוז), שזוהי באופן מפתיע תוצאה גבוהה מהאינטואיציה הראשונית (ולכן תוצאה זו בתורת ההסתברות נקראת 'פרדוקס'). היות שלא מדובר על יום הולדת ספציפי אלא כל זוג תואם, מספר הזוגות האפשריים בקבוצה כזו הוא רק <math>23\times 22/2=253</math>. במילים אחרות כדי שההסתברות ששני משתנים מקריים יהיו זהים מעל מרחב הסתברות <math>U</math> בהתפלגות אחידה בהסתברות גבוהה מחצי נדרשים לפחות <math>1.2\cdot |U|^{1/2}</math> מאורעות. במקרה של יום הולדת השורש הריבועי של 365 הוא בערך 19.10 ולכן צריכים להיות לפחות 23 אנשים, אך בכל הקשור לימי הולדת נתון זה אינו מדויק כיוון שהתפלגות הלידות אינה אחידה (למשל באוקטובר נולדים כ-5% יותר תינוקות בממוצע מאשר בחודשים האחרים בשנה).

העובדה שמבחינה סטטיסטית היתכנות של התנגשויות גבוהה יחסית ניתנת לניצול לשבירת פונקציית גיבוב (או כל פונקציה חד-כיוונית). הרעיון הוא שהמתקיף שמקבל לידיו קלט מסוים נניח <math>m</math> אותו הוא מעוניין לזייף ואת ערך הגיבוב שלו נניח <math>h(m)</math> המשמש כהוכחה למקוריותו. הוא מכין תחילה <math>r_1</math> וריאציות של <math>m</math> וכן <math>r_2</math> וריאציות של הקלט המזויף <math>m'</math> אותו הוא מעוניין להחליף איתו. את כל הערכים הוא מגבב ומאחסן בטבלה ממוינת. לאחר מכן הוא מחפש בטבלה שני קלטים האחד מקורי והשני מזויף שלהם ערך גיבוב זהה. במידה שנמצא זוג תואם כזה נניח <math>(m_i,m_i')</math> הוא יכול לשייך את ערך הגיבוב של <math>m_i</math> לקלט <math>m_i'</math> ולטעון שהוא מקורי היות שמתקיים <math>h(m_i')=h(m_i)</math>. ההבדלים בין הקלטים יכולים להיות כל הבדל קל שאינו משנה את משמעות התוכן כמו רווחים כפולים, שורות ריקות וכדומה. מבחינה הסתברותית מספר ההתנגשויות הצפוי הוא <math>r_1\cdot r_2/n</math> והסיכוי למצוא התנגשות אחת הוא בסדר גודל <math>1-\exp(-r_1\cdot r_2/2^n)</math> שהוא בערך 63% עם זיכרון בסדר גודל של <math>O(r)</math> כאשר <math>r=r_1=r_2=2^{n/2}</math>. יש להביא בחשבון גם את מיון הערכים שהוא בסיבוכיות של <math>O(r\log r)</math> וכן החיפוש שהוא בסיבוכיות <math>O(\log r)</math> אך פעולות אילו אינן משמעותיות ואפשר להתעלם מהן. את ההתקפה פיתח גידעון יובל ב-1979.

יתרה מזו, אפשר לצמצם את דרישות הזיכרון באופן משמעותי אם ממירים את בעיית חיפוש ההתנגשויות לבעיה אחרת מאוד דומה שנקראת בעיית מציאת מחזוריות של פונקציה אקראית. אם נתונה פונקציה אקראית <math>x_0, x_1=f(x_0),x_2=f(x_1),...</math>, קיימים אלגוריתמים מהירים למציאת שני ערכים <math>x_i,x_j</math> כך שמתקיים <math>f(x_i) = f(x_j)</math> כאשר <math>i\ne j</math> וזאת ללא צורך בזיכרון כלל. בנוסף אפשר ליישם את אלגוריתם החיפוש באופן מקבילי. לדוגמה בטכנולוגיה של 1994 אפשר היה לבנות בעלות של 10 מיליון דולר, חומרה ייעודית למציאת התנגשויות בפונקציית הגיבוב MD5 כאשר <math>n=128</math> בתוך 21 יום. בשנת 2004 במחיר נמוך מזה אפשר היה למצוא התנגשויות בתוך 4 שעות.

להתקפה זו השלכה מהותית על ביטחון כל פונקציית גיבוב. אם פונקציית גיבוב מפיקה פלט של <math>n</math> סיביות, בהנחה שלא קיימת נגדה התקפה טובה מכוח גס אז אומרים שביטחונה המרבי הוא בפקטור של כמחצית <math>n</math> ללא תלות באיכותה. למשל ב-SHA-1 פלט הפונקציה המינימלי הוא 160 סיביות ועל כן מציאת התנגשות בכוח גס היא בסיבוכיות של <math>2^{80}</math>. נכון לשנת 2015 מקובל להשתמש בערכי גיבוב באורך של לפחות 256 סיביות כדי לקבל ביטחון ברמה של <math>2^{128}</math> שהוא המינימום הנדרש כיום. ליתר דיוק מספיק שהזיכרון הפנימי של האלגוריתם יהיה גדול כדי לסכל התקפה זו ואילו ערך הגיבוב המתקבל ממנו ניתן ל"קיטום" לגודל הרצוי. הוכח שאם פונקציית הגיבוב בטוחה, הרי שאפשר ליטול רק חלק מתוצאת הגיבוב מבלי להסתכן בירידה בביטחון כל עוד אורך הגיבוב שמשתמשים בו מספיק גדול כדי למנוע ניחוש בכוח גס, למעשה זו השיטה הרווחת כיום.

==שימושים==
*הבטחת שלמות. השימוש העיקרי בפונקציית גיבוב הוא הבטחת שלמות של פיסת מידע דיגיטלי כמו קובץ, הודעת דואר, מפתח הצפנה או מסר כלשהו. תחילה מפיקים מהמסמך תמצית קצרה אותה שולחים יחד עם המסמך או מאחסנים במקום שמור. בנקודת זמן כלשהי, אם מעוניינים לוודא את שלמות המסמך מחשבים את פונקציית הגיבוב מתוכן המסמך הנוכחי ומשווים את התוצאה מול התמצית השמורה, אם ישנו הבדל משמע שבוצע שינוי. פונקציית הגיבוב מבטיחה מעצם הגדרתה שניסיון לבצע שינוי זדוני במסמך מבלי שהמשתמשים הלגיטימיים יבחינו בו יתגלה מיד היות שתמצית המסמך השמורה לא תתאים למסמך לאחר השינוי. אלא אם כן המתקיף מסוגל לשנות גם את התמצית. היות שהתמצית בדרך כלל מאומתת בדרך כלשהי לא סביר שהוא יצליח.
*חתימה דיגיטלית. פונקציית גיבוב בדרך כלל מהירה מאוד לכן מסיבות של יעילות כאשר רוצים לחתום חתימה דיגיטלית על מסמך גדול, עדיף תחילה להכין מהמסמך תמצית ולחתום עליה במקום לחתום על המסמך כולו. היות שיש התאמה חד-ערכית בין המסמך לתמצית שלו אם החתימה על התמצית נמצאת תקפה, הרי שעובדה זו מבטיחה שהמסמך עצמו אותנטי. בנוסף פונקציית גיבוב יכולה לשמש כבסיס לחתימה דיגיטלית חד-פעמית. הרעיון לחתימה דיגיטלית חד-פעמית מבוססת פונקציית גיבוב עלה כבר ב-1979 והסיבה שהיא אינה בשימוש נרחב כיום נובע בעיקר בגלל מפתחות חתימה ואימות גדולים מדי. לאורך השנים נעשו מאמצים להקטין את המפתחות, ביניהם הרעיון של שימוש בעץ גיבוב או בטביעת אצבע ציבורית.
*הגנה על סיסמאות. שיטה ותיקה לניהול סיסמאות נעשית באמצעות פונקציית גיבוב. סיסמאות לא נשמרות במצב גלוי מחשש לפריצה למערכת וגנבתן. לא מקובל להשתמש בפונקציית הצפנה כדי להגן על סודיות הסיסמאות מפני שלוש סיבות. א. אין צורך בפענוח כלל כי אפשר להשאיר את הסיסמאות במצב מוצפן. בכל ניסיון אימות השרת יכול להצפין את הסיסמה שהוקלדה על ידי המשתמש ולהשוות את התוצאה עם הסיסמה המוצפנת השמורה במערכת. מסיבה זו פונקציית גיבוב מועדפת כי אינה זקוקה למפתח הצפנה כלל. ב. יש עניין של מגבלות חוקיות על הצפנה חזקה במדינות מסוימות כמו ישראל לכן כל דרך שנמנעת מהצפנה עדיפה. ג. פונקציית גיבוב מהירה, פשוטה ויעילה יותר מפונקציית הצפנה. לכן מקובל שהשרת מאחסן רק את קוד הגיבוב של הסיסמאות וכאשר משתמש מעוניין להתחבר הוא מתבקש להקליד סיסמה, השרת מחשב את פונקציית הגיבוב של הסיסמה שהקליד ובודק האם הערך שהתקבל תואם לזה השמור במערכת, אם כן השרת מאשר את ההתחברות. אמנם זו שיטה יעילה ומקובלת בעולם כיום אך היא אינה מספקת הגנה הרמטית. למעשה אינה מונעת לחלוטין התקפת כוח גס על קובץ הסיסמאות כולו, גם אם הסיסמאות אינן שמורות במצב קריא. המתקיף יכול לגנוב את קובץ הסיסמאות המוצפנות, לנחש סיסמאות כלשהן, לבצע גיבוב שלהן ולבדוק האם התוצאה מופיעה בקובץ, גם אם לא של משתמש ספציפי. היות שהתקפה כזו יכולה להתבצע בצורה לא מקוונת, למתקיף יש זמן בשפע.
*אימות זהויות. דרך יותר בטוחה מאימות באמצעות סיסמה המציעה מה שקרוי "אימות חזק" היא סיסמה חד-פעמית. הרעיון הוצע לראשונה על ידי לזלי למפורט והוא שימוש בפונקציית גיבוב לצורך אימות זהויות ברשת לא בטוחה מבלי להשתמש בסיסמה קבועה. דוגמה למערכת כזו היא S/KEY.
*סכמת התחייבות. אפשר להכין סכמת התחייבות מפונקציית גיבוב, הרעיון הבסיסי פועל כדלהלן: אם אליס רוצה להוכיח לבוב ידיעת סוד מסוים אך אינה רוצה לחשוף אותו בפניו (כעת), היא יכולה להכין תמצית גיבוב מהסוד ולשלוח אותה לבוב כהתחייבות. בבוא העת כאשר הסוד נחשף בוב יכול לייצר ערך גיבוב חדש של הסוד ולהשוותו מול זה שאליס שלחה קודם. בדרך זו בוב יכול להבטיח שאליס לא שינתה את הסוד ולמעשה הסוד שנחשף הוא הסוד שהיא התחייבה על ידיעתו קודם לכן. לסכמות התחייבות שימושים במכרז והצבעה דיגיטליים.
*מחולל פסאודו-אקראי. פונקציית גיבוב קריפטוגרפית יכולה לשמש כבסיס למחולל פסאודו-אקראי. טכניקה זו מנוצלת בהרבה פרוטוקולים. במחולל פסאודו אקראי קריפטוגרפי מקובל לא להשתמש ישירות בערכים אקראיים שנאספו ממקורות שונים (כגון מחולל אקראי פיזי, פונקציה קריפטוגרפית או נתוני מערכת אקראיים חסרי חשיבות) זאת בגלל שההתפלגות הסטטיסטית שלהם עלולה להיות נמוכה, אלא תחת זאת מעבירים אותם בפונקציית גיבוב ותוצאת הגיבוב היא פלט המחולל הסופי (דוגמאות; האלגוריתמים Yarrow ו-TrueRand).
*פונקציית גזירת מפתח - Key derivation function (בקיצור KDF). פונקציית גיבוב קריפטוגרפית טובה לגזירת מפתחות הצפנה רבים מתוך מפתח מאסטר יחיד. כל אימת שזקוקים למפתח חדש מבצעים גיבוב של המפתח הקודם ולוקחים חלק מהתוצאה לפי הצורך כמפתח חדש. בגלל החד-כיווניות של פונקציית הגיבוב, יהיה קשה למתקיף לנסות לנחש את המפתחות שהופקו. אך אם עלה בידו לנחש את מפתח המאסטר יהיה קל לו לנחש את כל המפתחות כי הוא פשוט יכול להריץ את פונקציית הגיבוב בעצמו.

==סוגי פונקציות==
פונקציות גיבוב קריפטוגרפיות מתחלקות לשתי משפחות עיקריות:
*פונקציית גיבוב ללא מפתח; נקראת גם modification detection code בקיצור MDC. תפקידה להוות ייצוג תמציתי של המסר כך שיהיה אפשר לחשוף כל שינוי אפילו קל ביותר בסבירות גבוהה. דוגמאות שימוש; הגנה על סיסמאות וחתימה דיגיטלית. בסיסמאות למשל הן אינן נשמרות במצב גלוי אלא רק ערך הגיבוב שלהן נשמר ובחתימה דיגיטלית מסיבות של יעילות, החתימה מתבצעת על תמצית מהמסר במקום על המסר עצמו.
:פונקציית גיבוב ללא מפתח מוגדרת באופן כללי כך:
::<math>H : \{0,1\}^*\rightarrow \{0,1\}^n</math>
:הכוכבית מציינת שאורך המידע אינו קבוע ו-<math>n</math> הוא אורך התג בסיביות (למשל 160 סיביות ב-SHA-1 או 256 סיביות ב-SHA-2).
*פונקציית גיבוב עם מפתח; נקראת גם message authentication code בקיצור MAC ומשמשת בעיקר לאימות מסרים. היא מוגדרת באופן כללי כך:
::<math>H : \{0,1\}^k \times \{0,1\}^*\rightarrow \{0,1\}^n</math>
:<math>k</math> הוא אורך המפתח בסיביות ויכול להיות בכל אורך שרירותי שמתאים לגודל הבלוק שפונקציית הגיבוב מקבלת. אפשר להפוך כל פונקציית גיבוב לפונקציית MAC עם מפתח. דרך אחת נקראת HMAC והיא שילוב בטוח של המפתח הסודי עם המסר וערכים קבועים נוספים, על ידי XOR.

===מבנה מרקל-דמגרד===

מבנה טיפוסי של פונקציית גיבוב קריפטוגרפית מורכב משלושה שלבים עיקריים; שלב הכנה, הליבה שנקראת 'פונקציית תמצות' ושלב סיום אופציונלי. היות שבדרך כלל המסר גדול במידה נכרת מהקלט אותו מקבלת פונקציית התמצות הפנימית יש צורך ליישם שיטה כלשהי לחלוקה לבלוקים בגודל קבוע וריפוד הבלוק האחרון כאשר אורך המסר אינו מתחלק היטב. השיטה הנפוצה שנקראת MD strengthening הומצאה על ידי רונלד ריבסט והיא מיישמת את מבנה מרקל ודמגרד. בשיטה זו מחלקים את הקלט לבלוקים בגודל קבוע מוסיפים '1' בסוף המסר ומרפדים באפסים ואז מוסיפים בלוק אחד המייצג את גודל המסר בסיביות ומבצעים את פעולת הפונקציה על כל הבלוקים בזה אחר זה. מרקל ודמגרד הוכיחו שאם נתונה פונקציית כיווץ (compression function) חסינת התנגשויות (בקיצור CRHF) למשל פונקציה מהצורה <math>F : \{0,1\}^{n}\times \{0,1\}^{k} \rightarrow \{0,1\}^{k}</math> כאשר <math>k<n</math>, אפשר להכין ממנה פונקציית גיבוב בטוחה לגיבוב מסר בכל אורך רצוי, שגם היא חסינת התנגשויות. כלומר ביטחון המבנה האמור אינו חלש מביטחונה של הפונקציה הפנימית עצמה.

פונקציית התמצות <math>h</math> מקבלת מחרוזת סיביות <math>x</math> באורך קבוע וערך נוסף (בדרך כלל תוצאת הפונקציה מסבב קודם הנקרא chaining value) ומחזירה פלט באורך קבוע באמצעות חישוב אלגברי כלשהו או בהסתמך על פונקציית הצפנה, לפונקציה זו תכונה חשובה שנקראת אפקט כדור השלג, הכוונה היא שכל שינוי קל בקלט אפילו בסיבית אחת יגרום לשינוי גדול בפלט, כך בתוך מספר סבבים מיטשטש הקשר בין הקלט המקורי לפלט.

כמתואר בתרשים השיטה באופן כללי פועלת כדלהלן:
#הקלט <math>x</math> מחולק ל-<math>t</math> בלוקים בגודל <math>r</math> סיביות, <math>x=x_1,x_2,...,x_t</math>.
#אם <math>|x|</math> (אורך <math>x</math> בסיביות) אינו מתחלק ב-<math>r</math> בשלמותו מוסיפים '1' בבלוק <math>x_t</math> לאחר המידע ומשלימים באפסים. תוספת זו מכונה MD strengthening והיא הוכנסה לראשונה באלגוריתם MD4 של רונלד ריבסט.
#מוסיפים בלוק <math>x_{t+1}</math> שמכיל ייצוג של אורך המסר בסיביות.
#מכינים וקטור אתחול בגודל <math>r</math> סיביות, נקרא בקיצור <math>IV</math> ומציבים בבלוק <math>H_0</math>.
#מבצעים איטרציה של הפונקציה הפנימית; עבור כל הבלוקים <math>x_i</math> כאשר <math>i=1,...,t+1</math> מבצעים <math>H_i=h(H_{i-1},x_i)</math>. בכל סבב <math>h</math> מפיקה ערך ביניים <math>H_i</math> שנקרא chaining value שהוא תוצאת החישוב על הבלוק הנוכחי בשילוב עם פלט הבלוק הקודם <math>H_{i-1}</math>. מבנה הפונקציה הפנימית ואופן שילוב הערכים משתנה בהתאם לשיטה עליה בנוי האלגוריתם (כמתואר תרשים). בגמר כל הסבבים הפלט הוא <math>H_t</math>.
#לסיום טרנספומציה אופציונלית <math>g</math> ממירה את הפלט האחרון לתוצאה הסופית <math>h(x)</math>.

לסיכום האלגוריתם נראה כך:

:<math>H_0=IV, \ H_i=h(H_{i-1},x_i), \ 1 \le i \le t; \ h(x)=g(H_t)</math>

===פונקציית תמצות===
מבנים נפוצים לפונקציות תמצות, הפונקציה E מייצגת [[צופן בלוקים כלשהו, g מייצג פונקציה כלשהי שממירה את הקלט למפתח הצפנה שמתאים לצופן E, אם הקלט כבר מתאים כמפתח, אפשר להסיר את g.]]
פונקציית התמצות שנקראת גם פונקציית כיווץ (compression function) היא הליבה של פונקציית הגיבוב. אפשר להכין פונקציית תמצות חד-כיוונית וחסינת התנגשויות בשלושה אופנים עיקריים;
*פונקציית תמצות מבוססת צופן בלוקים; קיימים שלושה מודלים בטוחים לבניית פונקציית תמצות על בסיס צופן בלוקים (כמתואר בתרשים).
:#לפי מודל מטיאס-מאייר-אוסאס (האיור השמאלי בתרשים) הפונקציה היא <math>H_i=E_{g(H_{i-1})}(x_i)\oplus x_i</math>.
:#לפי מודל דויס-מאייר הפונקציה היא <math>H_i=E_{x_i}(H_{i-1})\oplus H_{i-1}</math>.
:#לפי מודל מיאגוצ'י-פרניל הפונקציה היא <math>E_{g(H_{i-1})}(x_i)\oplus x_i\oplus H_{i-1}</math>.
:באופן כללי הסתמכות על צופן בלוקים לבניית פונקציית גיבוב איטית יחסית ואינה נפוצה בשימוש.
*פונקציית תמצות ייעודית; זוהי פונקציה חד כיוונית חסינת התנגשויות (CRHF) שמבצעת סדרה של פעולות אריתמטיות בסיסיות תוך מתן דגש על ביצוע יעיל וקל ליישום במחשב הן בתוכנה והן בחומרה. קיימים מספר אלגוריתמים פופולריים שמסתמכים על פונקציית תמצות ייעודית. ביניהם אפשר למנות את משפחת תמצית המסרים של רונלד ריבסט, MD4 ו-MD5 וכן משפחת SHA בה כלולים שלושה אלגוריתמים SHA-2, SHA-1 ו-SHA-3 וכן RIPE-MD. שני האחרונים במשפחת SHA מומלצים כתקן גיבוב רשמי של ממשלת ארצות הברית המנוהל על ידי NIST.

*פונקציית גיבוב מבוססת אריתמטיקה מודולרית. פונקציה חד כיוונית שמסתמכת על בעיה מתורת המספרים שמאמינים שהיא קשה. סכמות מסוג זה בדרך כלל איטיות מאוד ומגיעות לתפוקה של בערך <math>\text{log}_2\text{log}_2N</math> סיביות פר העלאה בחזקה מודולרית אחת. <math>N</math> נקרא המודולוס והוא בדרך כלל בסגנון RSA - כפולה של שני מספרים ראשוניים סודיים <math>N=pq</math>. יש לציין שבמקרה של פונקציית גיבוב בעלת מבנה אלגברי כמו זו מכילה חולשה מובנית, קל להחדיר דלת אחורית לפרמטרים של הסכמה כדי לגרום להתנגשויות. מלבד זאת חלק מהפרמטרים אמורים להיות נסתרים מהעין, למשל הגורמים הראשוניים של <math>N</math>, ואסור לאף צד לראותם. לכן יש צורך לנקוט משנה זהירות בבחירת הפרמטרים. דרך אחת היא להיעזר בצד שלישי מהימן, ודרך אחרת היא שימוש בסכמת שיתוף בטוחה.

===פונקציית גיבוב מבוססת אריתמטיקה מודולרית===
איוון דמגרד הציע סכמה כזו המבוססת על צופן אל-גמאל וגיבסון ובלייר הציעו מבנים דומים המבוססים על בעיית לוגריתם דיסקרטי שפועלים מעל חבורה <math>G</math> מסדר ראשוני <math>p</math>. הרעיון הוא להכפיל את <math>t</math> הבלוקים של המסר עם <math>t</math> אלמנטים אקראיים <math>\alpha_i</math> מתוך <math>G</math>. ערך הגיבוב יהיה תוצאה של:

:<math>H_{t+1}=\prod_{i=1}^t \alpha_i^{\hat X_i}</math> (מודולו <math>p</math>).

כאשר <math>\hat X_i</math> הוא הבלוק <math>X_i</math> של המסר לאחר שרופד ב-'1' כדי למנוע מצב שהבלוק יהיה כולו מאופס. בכל אופן מרבית הסכמות המבוססות על אריתמטיקה מודולרית כמו זו הן סכמות שפותחו בשיטות אד הוק, לא הוכחו כבטוחות וחלקן הגדול אף נפרצו בקלות. במיוחד ראוי לציון תקן איזו 4–10118 (MASH) שנפרץ פעם אחר פעם באופן מביך, לאחר שתוקן ובכל פעם התגלו בו שוב חולשות. המבנה הכללי הטוב ביותר היודע הוא מהצורה:
:<math>\boldsymbol{H_i=((X_i\oplus H_{i-1})^2\ \text{mod }N)\oplus H_{i-1}}</math>.

כאשר <math>H_{i-1}</math> הוא ערך הביניים ו-<math>X_i</math> הם הבלוקים של המסר עם יתירות מוספת. חשוב מאוד להוסיף יתירות מכוונת למסר לפני הגיבוב כדי למנוע את 'התקפת בלוק מתקן' (להלן). הגרסה העדכנית של תקן איזו 4–10118 נכון לשנת 1998 (ISO/IEC 10118-4) נקראת MASH קיצור של modular arithmetic secure hash והיא מופיעה בשתי גרסאות MASH-1 ו-MASH-2. פונקציית התמצות הפנימית של MASH היא מהצורה:

:<math>H_i=(((\hat X_i\oplus H_{i-1})\lor A)^2\ (\text{mod }N))\dashv n\oplus H_{i-1}</math>

כאן <math>A=\text{0xF00..00} </math> הוא קבוע (בבסיס הקסדצימלי) וכן את הבלוקים <math>\hat X_i</math> בגודל <math>n</math> סיביות מכינים על ידי שמחלקים תחילה את המסר לבלוקים בגודל <math>n/2</math> סיביות ומרחיבים כל בלוק על ידי הוספת יתירות, מחלקים את המידע לחצאי בתים ומציבים '1111' בארבע הסיביות המשמעותיות הנותרות של כל בית. הסימן <math>\lor </math> מייצג OR, הסימן <math>\oplus</math> מייצג XOR והסימן <math>\dashv</math> אומר שתוצאת ההעלאה בריבוע נחתכת בכל סבב ל-<math>n</math> סיביות האחרונות. בנוסף התקן מגדיר פונקציה מסיימת מסובכת שנועדה למחוק כל זכר של המבנה האלגברי של הפונקציה. התוצאה האחרונה של פונקציית התמצות <math>H_{t+1}</math> מחולקת ל-4 תת-בלוקים, איתם מחשבים ברקורסיה עוד שנים-עשר בלוקים בגודל <math>n/4</math> סיביות <math>Y_i=Y_{i-1}\oplus Y_{i-4}</math>, מאחדים את כל 16 הבלוקים שנוצרו לשמונה בלוקים בני <math>n/2</math> סיביות <math>X_{t+1+i}=Y_{2i-2}\ \| \ Y_{2i-1}</math>, מרחיבים אותם לפי השיטה האמורה לעיל ומבצעים עוד שמונה סבבים של פונקציית התמצות על הבלוקים האחרונים. ולסיום התוצאה הסופית היא מחרוזת סיביות בגודל <math>n/2</math> המחושבת על ידי <math>H_{t+1+8}\text{ mod }p</math>. ההתקפה הטובה ביותר הידועה כנגד מבנה זה היא בסיבוכיות של <math>2^{n/2}</math> שהיא לא יותר טובה מכוח גס. MASH-2 היא גרסה שונה במעט שבה ההעלאה בריבוע מוחלפת ב-<math>e=2^8+1</math>.

====התקפת בלוק מתקן====
התקפת בלוק מתקן (correcting block) היא התקפה המנצלת את המבנה האלגברי של פונקציית התמצות הפנימית. ההתקפה מתמקדת בחיפוש התנגשויות או מקור נוסף על ידי החלפת בלוק אחד או יותר בסוף, באמצע או בהתחלה של המסר. ההתקפה מתבצעת על ידי חישוב <math>h(X\ \| \ Y)</math> כאשר <math>Y</math> הוא הבלוק המתקן. מבנה אלגברי פגיע במיוחד להתקפה זו משום שאפשר להפוך לפעמים את פונקציית התמצות הפנימית בעזרת מניפולציה אלגברית. דרך נפוצה להתמודד עם התקפה זו היא להוסיף יתירות מכוונת למסר לפני הגיבוב כך שיהיה קשה למצוא בלוק מתקן עם היתירות הדרושה. המחיר כמובן הוא ירידה בביצועים. לדוגמה ב-1984 הציעו דייוויס ופרייס פונקציית גיבוב עם פונקציית תמצות <math>f</math> כדלהלן: <math>f=(H_{i-1}\oplus X_i)^2\text{ mod }N</math>. היתירות שהם הוסיפו הייתה 64 אפסים שנוספו לכל בלוק לפנים או בסוף. גיראולט ואחרים הראו כיצד אפשר לתקוף פונקציה כזו ולמצוא מקור נוסף. CCITT X.509 הייתה פונקציית גיבוב שפותחה ב-1988 וניסתה למנוע את ההתקפה המתוארת על ידי הוספת היתירות באופן כזה שכל ניבל (חצי בית) בכל הבתים של המסר יכיל ארבעה אפסים. למרות זאת הראה קופרשמידט שאפשר למצוא התנגשויות במבנה זה באמצעות ההתקפה האמורה.

==מבנה ספוג==

פונקציית ספוג היא כלי קריפטוגרפי ורסטילי שיכול בין היתר לשמש כבסיס להכנת פונקציית גיבוב על ידי מה שקרוי "מבנה ספוג". מבנה ספוג הוא מצב הפעלה של פרמוטציה קבועה, עם כלל ריפוד מתאים, שמקבל כקלט מחרוזת בינארית <math>\mathbb{Z}^*_2</math> בכל אורך, מכיל זיכרון פנימי רחב ומפיק פלט <math>\mathbb{Z}^n_2</math> כאשר <math>n</math> מוגדר על ידי המשתמש. מבנה ספוג הוא הכללה של פונקציית גיבוב באופן שמאפשר קלט קבוע כמו בצופן זרם או פלט קבוע כמו באימות מסרים. הוא מכיל זיכרון, דהיינו הפונקציה הפנימית מופעלת באופן איטרטיבי על המצב הפנימי בשילוב עם הקלט. את ביטחון האלגוריתם מבטאים במונחים של גודל הזיכרון הפנימי. בפונקציית ספוג נעשה שימוש בפועל בכמה אלגוריתמים חדשים, ביניהם SHA-3.

==פונקציית גיבוב אקראית==

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

===פונקציית גיבוב אוניברסלית===
פונקציית גיבוב אוניברסלית או בשמה האחר TCR קיצור של Target Collision Resistance היא פונקציית גיבוב אקראית שאינה עמידה מפני התנגשויות באופן מלא. פונקציה זו פותחה בהשראת נאור ויונג שהציעו לראשונה את פונקציית הגיבוב האוניברסלית בקיצור UOWHF ששמה שונה לאחר מכן על ידי בלייר ורוגווי ל-TCR.

בניסוח רשמי, פונקציית גיבוב אוניברסלית היא בעצם משפחה של פונקציות <math>\{H_r\}_{r\in R}</math> עבור קבוצה כלשהי <math>R</math>. היא תקרא אוניברסלית או TCR אם לא קיים אלגוריתם יעיל <math>A</math> שאיתו אפשר לנצח במשחק הבא למעט בהסתברות זניחה. <math>A</math> בוחר קלט כלשהו <math>M</math> ומקבל ערך אקראי <math>r\in_R R</math> והוא צריך למצוא קלט אחר <math>M'\ne M</math> כך שמתקיים <math>H_r(M')=H_r(M)</math>. כאשר <math>H</math> היא פונקציית גיבוב כמו MD5 והערך <math>r</math> הוא מעין מפתח ונקרא גם "מלח". למתקיף אין שליטה על ערך זה, הוא חייב לקבל אותו עבור כל מסר שהוא מנסה לגבב. בדרך זו אפשר להפוך כל פונקציית גיבוב דטרמיניסטית ל-TCR. המלח <math>r</math> יכול להיות ערך קצר כלשהו אך חייב להיות חד-פעמי עבור כל מסר נתון.

מבנה זה נחשב יעיל ומבטיח קושי רב יותר במציאת התנגשויות כלומר למצוא <math>y</math> המקיים <math>H_r(x)=H_r(y)</math> מאשר במודל הסטנדרטי של פונקציות גיבוב. כאן התקפת יום הולדת אינה ישימה כיוון שהיא לא יכולה להיות אוף ליין, כלומר התוקף חייב לקבל בנוסף לתמצית הקלט את <math>r</math> שמיוצר באופן אקראי עבור כל מסר, לכן אפשר להסתפק בכל פונקציית גיבוב במבנה מרקל דמגרד שהיא בעלת עמידות מפני מציאת מקור נוסף ואינה חסינת התנגשויות (הגדרה 3 לעיל). הגדרה פורמלית של פונקציית גיבוב TCR היא:
<center>
:<math>H_r^c(M)=H_r^c(m_1,m_2,...,m_L)\ \overset{\underset{\mathrm{def}}{}}{ = }\ H^c(m_1\oplus r, m_2\oplus r, ..., m_L\oplus r)</math>
</center>
פשוט הקלט לפונקציית הגיבוב מחובר עם מחרוזת המלח הקצרה בלוק אחר בלוק ב-XOR לפני שמפעילים את פונקציית הגיבוב. בגלל השימוש במלח האקראי <math>r</math> לא תמיד הפונקציה ניתנת לשימוש כחלק ממנגנון חתימה דיגיטלית כי יש צורך לחתום גם על המלח ושלוח אותו יחד עם המסר לצד המקבל, מה שמחייב שינויים משמעותיים בקוד המקור של המערכות הקיימות. אפשר לפתור את הבעיה על ידי הכללת <math>r</math> כחלק מהמסר כך:
<center>
:<math>\tilde H_r^c(M)=H_r^c(0|M)\ \overset{\underset{\mathrm{def}}{}}{=}\ H^c(r,m_1\oplus r,m_2\oplus r..., m_L\oplus r)</math>.
</center>
כאן בנוסף לחיבור מחרוזת המלח הקצרה עם כל הבלוקים של הקלט, משרשרים את מחרוזת המלח עצמה בראש הקלט ואת הכול ביחד מגבבים עם פונקציית הגיבוב כרגיל. גרסה זו נקראת eTCR והיא מציעה ביטחון רב יותר, יתרונה הוא שאין צורך לחתום על המלח בנפרד וניתן להכניס את השינוי במערכות הקיימות ללא שינויים מרחיקי לכת בקוד המערכת.

==תקן פונקציית גיבוב בטוחה (SHA)==

במטרה ליצור תקן בין-לאומי אחיד של פונקציות גיבוב קריפטוגרפיות פרסם המכון הלאומי לתקנים וטכנולוגיה האמריקאי את תקן SHA קיצור של secure hash algorithm. בשנת 1993 פורסמה הראשונה מבין הפונקציות במשפחה שנקראה SHA-0 (האפס נוסף מאוחר יותר כדי להבדילה מהגרסאות המתקדמות). הפונקציה הוחלפה ב-1995 בגרסה המחוזקת SHA-1, עקב חולשות שנתגלו בה. SHA-1 דמתה ל-SHA-0 בשינויים קלים. שתי הפונקציות מבוססות על אלגוריתם תמצית מסרים של רונלד ריבסט MD5, פועלות בשיטת מרקל-דמגרד ומפיקות פלט באורך 160 סיביות. ב-2002 פרסם NIST את משפחת הפונקציות SHA-2, המפיקות ארבעה פלטים אפשריים 224, 256, 384 ו-512 סיביות.

משפחת SHA היא סדרת פונקציות גיבוב ייעודיות המבוססות על הידע שנצבר בעקבות סדרת האלגוריתמים MD (תמצית מסרים). פונקציות אלו נבנו תוך שימת דגש על פיזור אחיד של כל סיביות המסר באופן כזה שלכל חלקי המסר תהיה השפעה על הפלט. הפונקציות משתמשות בפעולות פשוטות כמו XOR, Shift ו-Rotate הבנויות כסדרה של פונקציות לוגיות המקבלות שלושה ערכים ומפיקות ערך אחד בגודל קבוע. כאשר ב-SHA1 וכן SHA256 הערכים בגודל מילה (32 סיביות) ואילו ב-SHA384 ו-SHA512 הערכים בגודל מילה כפולה (64 סיביות). ההבדל העיקרי בין הפונקציות השונות במשפחה הוא בכמות סיביות הפלט וערכי האתחול הקבועים.

בנובמבר 2007 הושקה תחרות פתוחה לתקן SHA החדש, בדומה לתחרות שהתקיימה לצפני בלוקים שבה זכה AES. באוקטובר 2012 נסגרה התחרות והוכרז Keccak האלגוריתם הזוכה בתחרות, זה שיחליף בהדרגה את קודמו לתפקיד ונקרא SHA-3. בארגון התקינה ממליצים שלא להשתמש יותר ב-SHA-1 וממליצים לעבור ל-SHA-2 או SHA-3. בארגון התקינה רואים בתקן SHA-2 עדיין בטוח לשימוש נכון לשנת 2013 ולא מתוכנן להחליפו בזמן הקרוב. העובדה ש-SHA-3 שונה מאוד בעיצובו ואופן פעולתו מתקן SHA-2 רק מרחיב את האפשרויות כיוון שלא סביר שתמצא התקפה אחת שתהיה יעילה כנגד שניהם. Keccak הזוכה בתחרות SHA-3 הוא אלגוריתם גיבוב יעיל ובטוח, שפותח על ידי קריפטוגרפים בלגיים ואיטלקיים. הוא מצטיין בגמישות רבה, שולי ביטחון גבוהים, ביצועים כלליים טובים ומימוש יעיל בחומרה. באלגוריתם זה הוכנס לראשונה מבנה הספוג הנחשב למבנה יעיל ובטוח.

==פונקציות גיבוב==
להלן רשימה חלקית של פונקציות גיבוב פופולריות, חלקן חדשות, חלקן היו בשימוש נרחב בעשור האחרון וחלקן לא בטוחות לאחר שהתגלו בהן חולשות והן מובאות כאן רק למען התיעוד. SHA-0 לא נכלל ברשימה גם משום שאינו בטוח כלל וגם משום שהוחלף בגרסאות מחוזקות שלו SHA-1 ו-SHA-2. ב-2005 דווחה התקפה תאורטית כנגד SHA-1 שמוצאת התנגשויות בזמן של <math>2^{69}</math> פעולות גיבוב (לעומת <math>2^{80}</math> כפי שמצפים מפונקציית גיבוב של 160 סיביות) ואף על פי שב-2010 דווחה התקפה מעשית בסדר גודל של <math>2^{61}</math>, הוא נכלל ברשימה כי עדיין נפוץ בשימוש נרחב. MD5 נפרץ לגמרי. ב-2004 בתוך ארבעה חודשים נמצאו התנגשויות בגרסה מלאה של MD5 בפרויקט שנקרא MD5CRK. ב-2005 ארג'ן לנסטרה הראה שאפשר לזייף סרטיפיקט X.509 בגרסה שעושה שימוש ב-MD5 באמצעות חיפוש התנגשויות בפונקציית הגיבוב, בתוך מספר שעות. ב-2010 דווחה התקפה נוספת, היעילה ביותר עד כה כנגד MD5 שפרטיה לא פורסמו אלא הוצעה כאתגר בסך 10,000 דולר למי שיצליח למצוא התנגשות עם 64 בתים עד ינואר 2013. ייתכן שהאלגוריתם נמצא עדיין בשימוש מוגבל והוא למעשה מוחלף כעת בהדרגה על ידי ארגוני התקינה הבינלאומיים באלגוריתם בטוח יותר.

להלן הרשימה:

{| class="wikitable"
|-
! שם הפונקציה !! אורך התג בסיביות
|-
| GOST|| 256
|-
| HAVAL|| 128/160/192/224/256
|-
| MD5 || 160
|-
| RIPEMD || 128/160/256
|-
| SHA-1 || 160
|-
| SHA-2 || 224/256/512
|-
| SHA-3 || 224/256/384/512
|-
| Tiger 2|| 192/128/160
|-
| Whirlpool|| 512
|-
| Skein || 256/512/1024
|-
| BLAKE || 224/256/384/512
|}

שלושת האלגוריתמים הראשונים HAVAL, GOST, MD5 וכן RIPEMD-128 לא מומלצים לשימוש כיום, והם מופיעים לצורך התיעוד בלבד. כמו כן ארגוני התקינה המליצו לעבור ל-SHA-2 ולא להשתמש יותר ב-SHA-1.

==ראו גם==
* SHA

==לקריאה נוספת==
<div class="mw-content-ltr">
* Douglas R. Stinson, Cryptography, Theory and Practice, CRC press, 1995. 
</div>

==קישורים חיצוניים==

* 

==הערות שוליים==

*
קטגוריה:פונקציות גיבוב
קטגוריה:קריפטוגרפיה

pl:Funkcja skr?tu#Kryptograficzne funkcje skr?tu