כשהייתי מפתח ווב צעיר, מיילים תמיד נראו לי כסוג של וודו שאלוהים יעזור אם משהו שם משתבש – במיוחד אם מייל נכנס לספאם או מסווג כמייל עויין. אבל בפועל המנגנונים של אבטחת המיילים ואימותם הם פשוטים. במאמר הזה אני מלמד על מנגנון DKIM. במאמר הקודם בסדרה כתבתי על אבטחת מיילים הסברתי על SPF ועל מיילים בכלל. קראו אותו לפני קריאת המייל הזה.
ראשי התיבות של DKIM הן: DomainKeys Identified Mail וגם היא, כמו SPF, אמורה למנוע מספאמרים לשלוח מייל בשם הדומיין ולשגר את המיילים שלא עברו את מבחן ה-DKIM הישר אל האשפה או אפילו יותר גרוע, אל התהום.
DKIM משתמשת בהצפנה אסימטרית – כלומר מפתח ציבורי ופרטי. בקישור יש מידע על ההצפנה הזו – אם אתם מפתחי ווב – באמת חובת קריאה. בגדול – יש לנו מפתח ציבורי ומפתח פרטי. עם המפתח הפרטי אני יכול להצפין ועם המפתח הציבורי אני יכול לפתוח את מה שהוצפן עם המפתח הפרטי. זה אומר שאני יכול לפרסם את המפתח הציבורי לכל דורש וכך להוכיח את זהותי.
איך? נניח הנה המפתח הציבורי שלי – אני מודיע עליו בעיתון, או ברשומת טקסט ב-DNS שלי, או אפילו ממש כאן, באתר שלי:
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCJ3feF7CA0UQiuCdWKf0Au7RBlp5h/TgbuB4aHFuMu5SP9QrQLF/Zf+hfb9goG4K+z8WQ4o9Redn7EtzdMeoawe2dOuJf+StQIoDnBUyn9X5lItbuzog9/YZBeB3XvWVlLKWDLujFYeKc4Vl4g90v/E6RE7BbustakBRa2cPnHuwIDAQAB
מחר בבוקר אתם מקבלים ממני מייל, אני נשבע בכל הקדוש והיקר לי שמדובר במייל ממני. אבל איך תדעו שזה מייל ממני? אני לוקח את תוכן המייל ומצפין אותו. איך אני מצפין אותו? אך ורק עם המפתח הפרטי שלי. שהוא פרטי. שלי ואמור להיות ידוע אך ורק לי. אני שולח את הטקסט המוצפן הישר אליכם.
BuRwxJtSrTjmsPWhDSnQnZc2WB8URK3wE23JdukmfUXVNgnIGfpiddxgUPY6MvwvtT0Hxxp/kNxgekBlaKiX5kWS4GyA1yRMB5NGVHu66YYhVk06kGyFwB4I3Mdq2TymsFx7Qbwhs8hSsiovKm9OwPgpw81ymzTM9IsOl/0EhSQ=
המפתח הציבורי שלי ידוע. הוא מפורסם פה ממש למעלה, ברשומת הדומיין שלי, בעיתון ואפילו הצטלמתי איתו בהשקה עם מלא דוגמניות. אתם לוקחים את הטקסט המוצפן ומנסים לפתוח אותו עם המפתח הציבורי. אם זה מצליח ואתם רואים את ההודעה המקורית שכתבתי. אתם יכולים לבדוק בעצמכם! הכנסו לאתר הזה למשל, הכניסו את הטקסט המוצפן, הכניסו את מפתח ההצפנה הציבורי ולחצו על decrypt. תקבלו את ההודעה שהיא זהה להודעה ששלחתי. רק מי שיש לו את המפתח הפרטי שתואם למפתח הציבורי יכול להצפין אותו בצורה כזו.
וככה זה עובד בדיוק עם DKIM. בכל משלוח של מייל. הנה השלבים:
בשליחה (השרת השולח) :
- שרת המייל השולח מצפין חלק מתוכן המייל על ידי מפתח פרטי שידוע רק לו.
- את הטקסט המוצפן הוא מציב בהדרים של המייל יחד עם מידע נוסף שאומר בגדול: "אני משתמש ב-DKIM, אני הנציג של שם המתחם הזה, את המפתח הציבורי אפשר להשיג אצלו".
בקבלה (השרת המקבל) :
- המייל נשלח כמו כל מייל ומתקבל על ידי שרת המייל המקבל.
- שרת המייל המקבל לוקח את המייל ומסתכל בהדרים. רואה שם DKIM עם תוכן מוצפן שמצהיר על זה שהוא משם מתחם מסוים.
- שרת המייל המקבל הולך לפי ההנחיות לשם המתחם של האתר ובודק אם יש לו שדה טקסט של DKIM עם מפתח ציבורי.
- יש שם המתחם רשומת טקסט עם מפתח ציבורי? מעולה! הוא פותח את הטקסט המוצפן עם המפתח הציבורי ומשווה אותו למייל הגלוי. תואם? עבר את המבחן. לא תואם? היאורה השליכוהו (או ל-DMARC, אבל זה סיפור אחר ולמאמר אחר).
בואו ונראה איך זה עובד בחי. אם אני מסתכל על ההדרים בג'ימייל שלי עם מייל שנשלח משרת שתומך ב-DKIM, אז אני אראה את תוצאות הבדיקה באופן די מפורש:
אפשר לראות שהבדיקה של DKIM עברה. אבל בואו ונראה איך היא עברה. נגלול למטה ונסתכל על ההדרים המקוריים ונחפש את DKIM-Signature :
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=mailchimp.com; s=k2; t=1591968304; [email protected]; bh=LFHTXLRL9iciS1pNDZmzhzyqSa88ZvR1m9Ztq74fP4U=; h=From:Reply-To:To:Date:Message-ID:Subject:MIME-Version:
Content-Type; b=qqQqgPqi+wvKiDpjfv9+9ktodbztiPlXjba5tcBx/Yw1CRMkWJi4rLpZnQj3O8mIM
k3wZqA/N3lU1rfx+pPsk6LLRyqTPbGmqwKG8ZwfPdfWuNKZxpUBThzuVJY9dTO2Mmq
c3Gbhf/OGBJvYfOzegNFCIjfWsRJpE6bA/3APdJGTrgUxxCCkl4hQ2+7ktiQ4n39jR
n1dxbKC2ltwgfxtwvNMlF/DKqsksBzwfc9D25nA5rg+OeMf92R2I7BXemGNc849uw7
qjG+wiJVHBjkCZvryizlJAux/hguf58Azte8Jb1Ur1jUURWxXRziy9QPhrE+IWJ+Fp
1umDsu8KIEKmg==
יש כמה פרמטרים. הראשון הוא הגרסה: v=1
השני הוא האלגוריתם של הגיבוב. a=rsa-sha256. חשוב עבור מה שיש ב-bh.
השלישי – c הוא מידת ההשוואה שאנו מבצעים. אנחנו משווים את תוכן המייל ויש שרתי מייל שבשליחה מורידים או מוסיפים רווחים וירידות שורה. אם אנחנו אומרים שהשוואת התוכן תתבצע אבל בלי הקפדה על זוטות כאלו, זה יהיה relaxed. זה חשוב עבור מה שיש בפרמטר bh.
הרביעי d הוא הדומיין שהמייל מצהיר שהוא בא ממנו. במקרה הזה mailchimp.com
החמישי הוא S והוא חשוב – הוא הסלקטור. התקן תומך בכמה וכמה מפתחות ציבוריים ופרטיים. כדי להפריד ביניהם אנו קובעים סלקטור שיכול להיות כל מילה שהיא. במקרה הזה מדובר ב-k2. זה הסלקטור. זאת אומרת ששרת המייל המקבל חייב לבדוק את הסלקטור הזה בבדיקה.
השישי – t – הוא לא חובה והוא מציין את הזמן שבו המייל הוצפן.
השביעי – i – גם הוא רשות ומציין את השולח עצמו. כתובת השולח או היוזר אייג'נט.
השמיני bh הוא חובה והוא ה-hash של כל ההודעה. עם ה-hash הזה אפשר לוודא שאף אחד לא שינה את תוכנה באמצע. במקרה שלנו זה LFHTXLRL9iciS1pNDZmzhzyqSa88ZvR1m9Ztq74fP4U – אם אין לכם מושג מה זה hash – המאמר הזה יוציא אתכם מהבוץ. ה-hash הזה נוצר עם אלגוריתם a תוך שימוש בהנחיות שיש ב-c.
התשיעי, שגם הוא חובה, הוא h ויש בו את רשימת כל ההדרים לפי הסדר שנמצאים את ההודעה שגובבה ב-bh
העשירי הוא b – והוא החשוב ביותר – זה התוכן המוצפן!
הודעה שנשלחת עם ההדרים האלו (למעט t ו-i שהם רשות) היא הודעה שנשלחת לפי כללי ה-DKIM. אבל מה יעשה מי שיקבל אותה? הבדיקה מתחילה בגישה ל-mailchimp.com ובדיקה אם יש להם את DKIM והסלקטור המפורט בפרמטר S. במקרה הזה k2. אנו עושים nslookup – אבל אפשר למקד את החיפוש בסלקטור ספציפי. זה נראה כך:
nslookup -type=txt k2._domainkey.mailchimp.com
החלק הראשון הוא פקודת ה-nslookup. השני הוא פלאג type שבו אנו מבקשים את הטקסט, את הסלקטור k2 שהופיע בפרמטר S. את המילה domainkey_ ואז את הדומיין שמפורט ב-d. במקרה שלנו mailchimp.com.
והפלא ופלא! אני מקבל מפתח ציבורי!
אם אני לא מקבל – יש לי בעיה והמייל ייכשל באופן מחפיר בבדיקת ה-DKIM. אבל אני מקבל ומקבל מפתח תחת פרמטר p:
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAx8zbrSuBn2HCE6a3H24TOo8MNqOVfKan83iOnG7cvFmpKLb048VSG49QWbmOV7beOG22EVBUU7b3IpQ3nwYptI1kMllSmjpOOpCK+GxZGHOum3cPx65G/862R39MKHsnsZyHZh+7aWyjM78qDfHmDgFGppC3OZzmUId57WawpDHhpTi0+z1UUQ0K50fkiY+qRNjkBRqjsD" "058E12U97CBk8yD5bl78uARCszn2PVWoXTljmQ0DPkOU/fTxiVG3YBEUrtscEBqYnxxlAj1APkO3dr9wQLbsuZUAM+zBJ3EKnMEbaG2fX7QEz/mTknQqg6uJVu8YO6m8yExJV0cTBgrQIDAQAB
עכשיו אני יכול להשתמש במפתח הציבורי הזה, לפענח את מה שיש בפרמטר b ולראות אם הוא תואם למה שיש בהודעה. תואם? מעולה. הבדיקה עברה. שרת המייל ותוכנת המייל יסווגו את המייל כעובר מבחינת DKIM וכתקין.
שרתי המייל גם יכולים להבטיח שאף אחד לא שינה את המייל באמצעות חישוב של פרמטר bh. לוקחים את תוכן ההודעה ומגבבים אותו לפי האלגוריתם שנמצא ב-a ולפי הכלל שיש ב-c (מתחשב ברווחים ובירידות שורה או לא) ואז גם לציין אם יש פה שינוי בתוכן ההודעה. במידה והגיבוב זהה – אין שינוי וההודעה הגיעה אלינו כפי שהיא נשלחה.
באופן עקרוני, על מנת לוודא שה-DKIM שלנו עובד, אנחנו צריכים לשלוח מייל ולראות אם בהדר יש DKIM pass כמו שהראיתי בהתחלה. במידה ואין? אנו חייבים לוודא שיש לנו DKIM בדומיין. במידה ולא – לבדוק עם מי שמנהל את שרת המייל איזה ערך להציב שם ואז להציב אותו.
ניתן להשתמש ב-DKIM או ב-SPF או בשניהם. שניהם תקנים שעובדים ומספיק להשתמש באחד מהם כדי לעבור את תוכנות האנטי ספאם הקשוחות. שימוש ב-DKIM נותן גם בדיקת וידוא לתוכן המייל, אם הוא לא השתנה. במה לבחור? תלוי בצרכים ובמשאבים.
אבל איך אני מציין שאני משתמש באחד מהם? או בשניהם? ואיך אני יכול לקבל התראות אם איזה ספאמר או סקאמר מנסה לשלוח מייל בשמי? זאת ועוד במאמר הבא על DMARC.
מקורות נוספים בעברית על DKIM
- Digital Whisper – אני מאמין שרובכם מכירים את המגזין המשובח הזה – יש בו מאמר מוצלח על DKIM מאת עוז אבנשטיין. יש גם תרשים מוצלח שם.
- באיגוד האינטרנט יש שפע של מידע על מנגנוני אימות מיילים.
12 תגובות
תעלה תמונה שלך עם הצופן והדוגמניות….
כמו תמיד – אחלה מאמר
יש מצב ששיקרתי קצת… 🙁
עירבבת בפוסט קצת בין dkim ו-dmarc (שבהחלט מגיע לו פוסט משלו).
אני שמח לראות שתוקן.
תודה! כן, זה העונש על search & replace שבוצע ברשלנות 🙂 המאמר בשבוע הבא על DKIM.
אחלה מאמר מתומצת ומסביר DKIM על רגל אחת
מחכה למאמר של שבוע הבא
איך אפשר שיהיה גיבוב וגם relaxed, הרי כל רווח ישנה את הגיבוב?
"הולך לפי ההנחיות לשם המתחם של האתר ובודק אם יש לו שדה טקסט של DKIM עם מפתח ציבורי" – איך שמים שם את המפתח הציבורי כך שידע למצוא אותו, ברמה הטכנית?
מה תוכן ההודעה ששלחת בדוגמה של ההצפנה?
כמה הערות בקצרה
•בעיקרון DKIM אינו מצפין אלא חותם
•קריטי לדאוג ששדה h יכיל שדות שיהפכו אותו ליחודי למשל תאריך (שכולל את השעה) Message ID
•שדה bh הוא ה hash של השדות שהוגדרו ב h
•שדה b כולל את החתימה הדיגיטלית של bh
•השרת המקבל בונה את ההדרים משדה h מייצר את ה Hash מחדש לפי האלגוריתים שהוגדר a ובעזרת המפתח הציבורי מרשומת ה DNS, מוודא שה Hash החדש תואם ל hash החתום.
•כל הסיפור מוגבל בזמן לפי שדות x ו t כדי למנוע שימוש רב פעמי (non-repudiation) ולכן הם אולי לא חובה מבחינת ה RFC אבל חובה להשתמש בהם
• להבדיל מ SPF שהוא סטטי, ובכל זמן ניתן לראות את רשומות ה SPF של הארגון, DKIM הוא דינמי, וניתן להגדיר כמות גדולה של רשומות ולהשתמש באחת אחרת כל פעם. את רשומת ה spf ניתן למצוא בקלות כאשר כדי למצוא את רשומת ה DKIM צריך לקבל מייל ספציפי.
בנושא DMARC אמתין עד שתכתוב על DMARC…
זה בדיוק הפוך ממה שכתבת:
"עם המפתח הפרטי אני יכול להצפין ועם המפתח הציבורי אני יכול לפתוח את מה שהוצפן עם המפתח הפרטי."
צריך לכתוב:
"עם המפתח הציבורי אני יכול להצפין ועם המפתח הפרטי אני יכול לפתוח את מה שהוצפן עם המפתח הציבורי."
נהדר, כמו תמיד
שאלת תם:
אז בעצם, הפעולה הזו נועדה לוודא אמינות על-בסיס התאמת פרמטר S?
כתבת שהתקן תומך בכמה מפתחות ציבוריים.
האם יהיה נכון לומר שספאמר יכול לנחש את פרמטר S, כי הוא אחד מתוך קבוצה לא כזו גדולה, ולעבור מבחן DKIM "בפוקס"?