DKIM לאבטחת מיילים

מנגנון אבטחת מייל שעובד עם מפתחות הצפנה.

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

ראשי התיבות של DKIM הן: DomainKeys Identified Mail וגם היא, כמו SPF, אמורה למנוע מספאמרים לשלוח מייל בשם הדומיין ולשגר את המיילים שלא עברו את מבחן ה-DKIM הישר אל האשפה או אפילו יותר גרוע, אל התהום.

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

איך? נניח הנה המפתח הציבורי שלי – אני מודיע עליו בעיתון, או ברשומת טקסט ב-DNS שלי, או אפילו ממש כאן, באתר שלי:

MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCJ3feF7CA0UQiuCdWKf0Au7RBlp5h/TgbuB4aHFuMu5SP9QrQLF/Zf+hfb9goG4K+z8WQ4o9Redn7EtzdMeoawe2dOuJf+StQIoDnBUyn9X5lItbuzog9/YZBeB3XvWVlLKWDLujFYeKc4Vl4g90v/E6RE7BbustakBRa2cPnHuwIDAQAB

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

BuRwxJtSrTjmsPWhDSnQnZc2WB8URK3wE23JdukmfUXVNgnIGfpiddxgUPY6MvwvtT0Hxxp/kNxgekBlaKiX5kWS4GyA1yRMB5NGVHu66YYhVk06kGyFwB4I3Mdq2TymsFx7Qbwhs8hSsiovKm9OwPgpw81ymzTM9IsOl/0EhSQ=

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

וככה זה עובד בדיוק עם DKIM. בכל משלוח של מייל. הנה השלבים:

בשליחה (השרת השולח) :

  1. שרת המייל השולח מצפין חלק מתוכן המייל על ידי מפתח פרטי שידוע רק לו.
  2. את הטקסט המוצפן הוא מציב בהדרים של המייל יחד עם מידע נוסף שאומר בגדול: "אני משתמש ב-DKIM, אני הנציג של שם המתחם הזה, את המפתח הציבורי אפשר להשיג אצלו".

בקבלה (השרת המקבל) :

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

בואו ונראה איך זה עובד בחי. אם אני מסתכל על ההדרים בג'ימייל שלי עם מייל שנשלח משרת שתומך ב-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.

והפלא ופלא! אני מקבל מפתח ציבורי!

k2._domainkey.mailchimp.com	canonical name = dkim2.mcsv.net.
dkim2.mcsv.net	text = "k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAx8zbrSuBn2HCE6a3H24TOo8MNqOVfKan83iOnG7cvFmpKLb048VSG49QWbmOV7beOG22EVBUU7b3IpQ3nwYptI1kMllSmjpOOpCK+GxZGHOum3cPx65G/862R39MKHsnsZyHZh+7aWyjM78qDfHmDgFGppC3OZzmUId57WawpDHhpTi0+z1UUQ0K50fkiY+qRNjkBRqjsD" "058E12U97CBk8yD5bl78uARCszn2PVWoXTljmQ0DPkOU/fTxiVG3YBEUrtscEBqYnxxlAj1APkO3dr9wQLbsuZUAM+zBJ3EKnMEbaG2fX7QEz/mTknQqg6uJVu8YO6m8yExJV0cTBgrQIDAQAB;"

אם אני לא מקבל – יש לי בעיה והמייל ייכשל באופן מחפיר בבדיקת ה-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

  1. Digital Whisper – אני מאמין שרובכם מכירים את המגזין המשובח הזה – יש בו מאמר מוצלח על DKIM מאת עוז אבנשטיין. יש גם תרשים מוצלח שם.
  2. באיגוד האינטרנט יש שפע של מידע על מנגנוני אימות מיילים.

פוסטים נוספים שכדאי לקרוא

רספברי פיי

הרצת גו על רספברי פיי

עולם הרספברי פיי והמייקרים ניתן לתפעול בכל שפה – לא רק פייתון או C – כאן אני מסביר על גו

תמונה מצוירת של רובוט שמנקה HTML
יסודות בתכנות

סניטציה – למה זה חשוב

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

גלילה לראש העמוד