הגדרה של אבטחת רשת

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

  • עוגני אמון בהתאמה אישית: אפשר להתאים אישית את רשויות האישורים (CA) שנחשבות מהימנות לחיבורים המאובטחים של האפליקציה. לדוגמה, אמון באישורים מסוימים עם חתימה עצמית או הגבלת הקבוצה של רשויות האישורים הציבוריות שהאפליקציה סומכת עליהן.
  • עקיפות לצורך ניפוי באגים בלבד: ניפוי באגים בטוח של חיבורים מאובטחים באפליקציה, בלי סיכון נוסף לבסיס המשתמשים שמותקנת אצלם האפליקציה.
  • ביטול ההסכמה לשימוש בתעבורת נתונים ללא הצפנה: הגנה על האפליקציות מפני שימוש בטעות בתעבורת נתונים ללא הצפנה.
  • הסכמה לשקיפות אישורים: הגבלת החיבורים המאובטחים של האפליקציה לשימוש באישורים שרשומים ביומן וניתנים להוכחה.
  • הצמדת אישורים: הגבלת החיבור המאובטח של האפליקציה לאישורים מסוימים.

הוספת קובץ תצורה של אבטחת רשת

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

<?xml version="1.0" encoding="utf-8"?>
<manifest ... >
    <application android:networkSecurityConfig="@xml/network_security_config"
                    ... >
        ...
    </application>
</manifest>

התאמה אישית של רשויות אישורים מהימנות

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

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

כברירת מחדל, חיבורים מאובטחים (באמצעות פרוטוקולים כמו TLS ו-HTTPS) מכל האפליקציות סומכים על רשויות אישור התעודות (CA) המותקנות מראש במערכת, ואפליקציות שמטרגטות ל-Android 6.0 (רמת API ‏23) וגרסאות ישנות יותר סומכות כברירת מחדל גם על מאגר רשויות אישור התעודות שנוספו על ידי המשתמש. אפשר להתאים אישית את החיבורים של האפליקציה באמצעות base-config (להתאמה אישית ברמת האפליקציה) או domain-config (להתאמה אישית לכל דומיין).

הגדרת רשות אישורים בהתאמה אישית

יכול להיות שתרצו להתחבר למארח שמשתמש באישור SSL בחתימה עצמית, או למארח שאישור ה-SSL שלו הונפק על ידי רשות אישורים לא ציבורית שאתם סומכים עליה, כמו רשות האישורים הפנימית של החברה. קטע הקוד הבא מראה איך להגדיר את האפליקציה ל-CA בהתאמה אישית ב-res/xml/network_security_config.xml:

<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
    <domain-config>
        <domain includeSubdomains="true">example.com</domain>
        <trust-anchors>
            <certificates src="@raw/my_ca"/>
        </trust-anchors>
    </domain-config>
</network-security-config>

מוסיפים את אישור ה-CA החתום בעצמו או הלא ציבורי, בפורמט PEM או DER, אל res/raw/my_ca.

הגבלת הקבוצה של רשויות אישורים מהימנות

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

ההגדרה של הגבלת הקבוצה של רשויות ה-CA המהימנו דומה להענקת אמון ברשות CA מותאמת אישית לדומיין ספציפי, מלבד זאת שמספר רשויות CA מצוינות במשאב. קטע הקוד הבא מראה איך להגביל את קבוצת רשויות האישורים המהימנה של האפליקציה ב-res/xml/network_security_config.xml:

<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
    <domain-config>
        <domain includeSubdomains="true">secure.example.com</domain>
        <domain includeSubdomains="true">cdn.example.com</domain>
        <trust-anchors>
            <certificates src="@raw/trusted_roots"/>
        </trust-anchors>
    </domain-config>
</network-security-config>

מוסיפים את רשויות האישורים המהימנו, בפורמט PEM או DER, אל res/raw/trusted_roots. שימו לב: אם משתמשים בפורמט PEM, הקובץ חייב להכיל רק נתוני PEM, ללא טקסט נוסף. אפשר גם לספק כמה רכיבים של <certificates> במקום אחד.

איך נותנים אמון ברשות אישורים נוספות

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

<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
    <base-config>
        <trust-anchors>
            <certificates src="@raw/extracas"/>
            <certificates src="system"/>
        </trust-anchors>
    </base-config>
</network-security-config>

הגדרת רשויות אישור (CA) לניפוי באגים

כשמנסים לנפות באגים באפליקציה שמתחבר דרך HTTPS, מומלץ להתחבר לשרת פיתוח מקומי שאין בו את אישור ה-SSL של שרת הייצור. כדי לתמוך בכך בלי לבצע שינויים בקוד של האפליקציה, אפשר לציין רשויות אישור (CA) לצורכי ניפוי באגים בלבד, שיהיו מהימנות רק כשהערך של android:debuggable הוא true, באמצעות debug-overrides. בדרך כלל, סביבות פיתוח משולבות וכלי build מגדירים את הדגל הזה באופן אוטומטי לגרסאות build שלא מיועדות להפצה.

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

בקטע הבא מוסבר איך לציין רשויות אישור לצורכי ניפוי באגים בלבד בקובץ res/xml/network_security_config.xml:

<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
    <debug-overrides>
        <trust-anchors>
            <certificates src="@raw/debug_cas"/>
        </trust-anchors>
    </debug-overrides>
</network-security-config>

הצטרפות לתוכנית שקיפות האישור

הערה: התמיכה בשקיפות האישורים זמינה רק מ-Android מגרסה 16 (רמת API 36).

שקיפות אישורים (CT, ‏ RFC 9162) היא תקן אינטרנט שנועד לשפר את האבטחה של אישורים דיגיטליים. היא מחייבת את רשויות האישורים לשלוח את כל האישורים שהן מנפיקות ליומן ציבורי שבו הם מתועדים, וכך לשפר את השקיפות ואת האחריות בתהליך הנפקת האישורים.

בעזרת CT, שמאפשר לשמור תיעוד מאומת של כל האישורים, קשה יותר לגורמים זדוניים לזייף אישורים או לרשויות אישורים להנפיק אותם בטעות. כך אפשר להגן על המשתמשים מפני מתקפות אדם בתווך ומפני איומי אבטחה אחרים. למידע נוסף, קראו את ההסבר באתר transparency.dev.

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

ביטול ההסכמה לתנועה בטקסט ללא הצפנה

הערה: ההנחיות שבקטע הזה רלוונטיות רק לאפליקציות שמטרגטות את Android מגרסה 8.1 (API ברמה 27) ומטה. החל מגרסה 9 של Android‏ (רמת API 28), התמיכה בטקסט ללא הצפנה מושבתת כברירת מחדל.

אם אתם רוצים שהאפליקציה תתחבר ליעדים באמצעות חיבורים מאובטחים בלבד, תוכלו לבטל את התמיכה בטקסט ללא הצפנה (באמצעות פרוטוקול HTTP לא מוצפן במקום HTTPS) ליעדים האלה. האפשרות הזו עוזרת למנוע נסיגה (רגרסיה) לא מכוונת באפליקציות בגלל שינויים בכתובות URL שסופקו ממקורות חיצוניים, כמו שרתי קצה. פרטים נוספים זמינים בכתובת NetworkSecurityPolicy.isCleartextTrafficPermitted().

לדוגמה, יכול להיות שתרצו לוודא שהאפליקציה תמיד תיצור חיבורים אל secure.example.com דרך HTTPS כדי להגן על תעבורת נתונים רגישים מרשתות עוינות.

בקטע הבא מוסבר איך לבטל את ההסכמה להעברת טקסט ללא הצפנה ב-res/xml/network_security_config.xml:

<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
    <domain-config cleartextTrafficPermitted="false">
        <domain includeSubdomains="true">secure.example.com</domain>
    </domain-config>
</network-security-config>

הצמדת אישורים

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

כדי להצמיד אישורים, מספקים קבוצת אישורים לפי גיבוב של המפתח הציבורי (SubjectPublicKeyInfo של אישור X.509). שרשרת אישורים תקפה רק אם היא מכילה לפחות אחד מהמפתחות הציבוריים המוצמדים.

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

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

בקטע הבא מוסבר איך להצמיד אישורים ב-res/xml/network_security_config.xml:

<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
    <domain-config>
        <domain includeSubdomains="true">example.com</domain>
        <pin-set expiration="2018-01-01">
            <pin digest="SHA-256">7HIpactkIAq2Y49orFOOQKurWxmmSFZhBCoQYcRhJ3Y=</pin>
            <!-- backup pin -->
            <pin digest="SHA-256">fwza0LRMXouZHRC8Ei+4PyuldPDcf3UKgO/04cDM1oE=</pin>
        </pin-set>
    </domain-config>
</network-security-config>

התנהגות של ירושה של הגדרות

ערכים שלא מוגדרים בהגדרה ספציפית עוברים בירושה. כך אפשר להגדיר הגדרות מורכבות יותר ועדיין לשמור על הקריאוּת של קובץ התצורה.

לדוגמה, ערכים שלא מוגדרים ב-domain-config נלקחים מההורה domain-config, אם הם בתצוגת עץ, או מה-base-config, אם לא. ערכים שלא מוגדרים ב-base-config יקבלו את ערכי ברירת המחדל של הפלטפורמה.

לדוגמה, נניח שכל החיבורים לתת-דומיינים של example.com חייבים להשתמש בקבוצה מותאמת אישית של רשויות אישור. בנוסף, תנועה ללא הצפנה לדומיינים האלה מותרת למעט כשמתחברים אל secure.example.com. כשמקפלים את ההגדרה של secure.example.com בתוך ההגדרה של example.com, אין צורך לשכפל את trust-anchors.

הקטע הבא מראה איך ייראה ההטמעה הזו ב-res/xml/network_security_config.xml:

<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
    <domain-config>
        <domain includeSubdomains="true">example.com</domain>
        <trust-anchors>
            <certificates src="@raw/my_ca"/>
        </trust-anchors>
        <domain-config cleartextTrafficPermitted="false">
            <domain includeSubdomains="true">secure.example.com</domain>
        </domain-config>
    </domain-config>
</network-security-config>

הפורמט של קובץ התצורה

התכונה 'הגדרת אבטחת הרשת' משתמשת בפורמט של קובץ XML. המבנה הכללי של הקובץ מוצג בקטע הקוד הבא:

<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
    <base-config>
        <trust-anchors>
            <certificates src="..."/>
            ...
        </trust-anchors>
    </base-config>

    <domain-config>
        <domain>android.com</domain>
        ...
        <trust-anchors>
            <certificates src="..."/>
            ...
        </trust-anchors>
        <pin-set>
            <pin digest="...">...</pin>
            ...
        </pin-set>
    </domain-config>
    ...
    <debug-overrides>
        <trust-anchors>
            <certificates src="..."/>
            ...
        </trust-anchors>
    </debug-overrides>
</network-security-config>

בקטעים הבאים מתוארים התחביר ופרטים נוספים של פורמט הקובץ.

<network-security-config>

יכול להכיל:
0 או 1 מ-<base-config>
כמות בלתי מוגבלת של <domain-config>
0 או 1 מ-<debug-overrides>

<base-config>

תחביר:
<base-config cleartextTrafficPermitted=["true" | "false"]>
    ...
</base-config>
יכול להכיל:
<trust-anchors> <certificateTransparency>
description:
הגדרת ברירת המחדל שמשמשת את כל החיבורים שהיעדים שלהם לא מכוסים ב-domain-config.

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

הגדרת ברירת המחדל לאפליקציות שמטרגטות ל-Android 9 (רמת API 28) ואילך היא:

<base-config cleartextTrafficPermitted="false">
    <trust-anchors>
        <certificates src="system" />
    </trust-anchors>
</base-config>

הגדרת ברירת המחדל לאפליקציות שמטרגטות את Android מגרסה 7.0 (רמת API‏ 24) עד Android מגרסה 8.1 (רמת API‏ 27) היא:

<base-config cleartextTrafficPermitted="true">
    <trust-anchors>
        <certificates src="system" />
    </trust-anchors>
</base-config>

הגדרת ברירת המחדל לאפליקציות שמטרגטות ל-Android 6.0 (רמת API ‏23) ומטה היא:

<base-config cleartextTrafficPermitted="true">
    <trust-anchors>
        <certificates src="system" />
        <certificates src="user" />
    </trust-anchors>
</base-config>

<domain-config>

תחביר:
<domain-config cleartextTrafficPermitted=["true" | "false"]>
    ...
</domain-config>
יכול להכיל:
<domain> אחד או יותר
<certificateTransparency> אפס או אחד
<trust-anchors> אפס או אחד
<pin-set> אפס או אחד
<domain-config>
מספר לא מוגבל של ערכי <domain-config> בתצוגת עץ
description:
הגדרה שמשמשת לחיבורים ליעדים ספציפיים, כפי שמוגדרים על ידי הרכיבים domain.

שימו לב: אם יש כמה רכיבי domain-config שמכסים יעד מסוים, המערכת משתמשת בהגדרה עם כלל הדומיין התואם הספציפי ביותר (הארוך ביותר).

<domain>

תחביר:
<domain includeSubdomains=["true" | "false"]>example.com</domain>
מאפיינים:
includeSubdomains
אם "true", כלל הדומיין הזה תואם לדומיין ולכל תת-הדומיינים, כולל תת-דומיינים של תת-דומיינים. אחרת, הכלל יחול רק על התאמות מדויקות.

<certificateTransparency>

תחביר:
<certificateTransparency enabled=["true" | "false"]/>
description:
אם הערך של true הוא true, האפליקציה תשתמש ביומני Certificate Transparency כדי לאמת אישורים. כשאפליקציה משתמשת באישור משלה (או באחסון המשתמש), סביר להניח שהאישור לא ציבורי ולכן לא ניתן לאמת אותו באמצעות שקיפות האישורים. כברירת מחדל, האימות מושבת במקרים האלה. עדיין אפשר לאלץ את האימות באמצעות <certificateTransparency enabled="true"/> בהגדרות הדומיין. לכל <domain-config>, ההערכה מתבצעת לפי הסדר הבא:
  1. אם certificateTransparency מופעל, מפעילים את האימות.
  2. אם כל <trust-anchors> הוא "user" או מוטמע (כלומר "@raw/cert.pem"), משביתים את האימות.
  3. אחרת, אפשר להסתמך על ההגדרות שעברו בירושה.

<debug-overrides>

תחביר:
<debug-overrides>
    ...
</debug-overrides>
יכול להכיל:
0 או 1 <trust-anchors>
description:
החלפות שיוחלו כשהערך של android:debuggable הוא "true". בדרך כלל זה המצב בגרסאות build לא ייעודיות להפצה שנוצרות על ידי סביבת פיתוח משולבת (IDE) וכלי build. עוגני האמינות שצוינו ב-debug-overrides מוסיפים לכל ההגדרות האחרות, והצמדת האישורים לא מתבצעת כששרשרת האישורים של השרת משתמשת באחד מעוגני האמינות האלה לצורך ניפוי באגים בלבד. אם הערך של android:debuggable הוא "false", המערכת מתעלמת מהקטע הזה לגמרי.

<trust-anchors>

תחביר:
<trust-anchors>
...
</trust-anchors>
יכול להכיל:
כמות בלתי מוגבלת של <certificates>
description:
קבוצה של עוגני אמון לחיבורים מאובטחים.

<certificates>

תחביר:
<certificates src=["system" | "user" | "raw resource"]
              overridePins=["true" | "false"] />
description:
קבוצה של אישורי X.509 לרכיבי trust-anchors.
מאפיינים:
src
המקור של אישורי ה-CA. כל אישור יכול להיות אחד מהסוגים הבאים:
  • מזהה משאב גולמי שמצביע לקובץ שמכיל אישורי X.509. האישורים צריכים להיות מקודדים בפורמט DER או PEM. במקרה של אישורי PEM, אסור שהקובץ יכיל נתונים נוספים שאינם PEM, כמו תגובות.
  • "system" לאישורי ה-CA של המערכת שמותקנים מראש
  • "user" לאישורי CA שנוספו על ידי משתמשים
overridePins

המדיניות קובעת אם רשויות האישורים מהמקור הזה עוקפות את ההצמדה של האישורים. אם הערך של "true" הוא 0, המערכת לא תצמיד שרשרות אישורים שנחתמו על ידי אחת מרשויות האישורים מהמקור הזה. אפשר להשתמש באפשרות הזו כדי לנפות באגים ב-CA או כדי לבדוק התקפות אדם בתווך על התנועה המאובטחת של האפליקציה.

ברירת המחדל היא "false", אלא אם מצוין אחרת ברכיב debug-overrides, במקרה כזה ברירת המחדל היא "true".

<pin-set>

תחביר:
<pin-set expiration="date">
...
</pin-set>
יכול להכיל:
כמות בלתי מוגבלת של <pin>
description:
קבוצה של סיכות של מפתחות ציבוריים. כדי שחיבור מאובטח יהיה מהימן, אחד מהמפתחות הציבוריים בשרשרת האמון צריך להופיע בקבוצת הסיכות. הפורמט של הסיכות מפורט במאמר <pin>.
מאפיינים:
expiration
התאריך, בפורמט yyyy-MM-dd, שבו יפוג התוקף של הסיכות, וכך יושבתו. אם לא מגדירים את המאפיין, התוקף של התגים לא יפוג.

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

<pin>

תחביר:
<pin digest=["SHA-256"]>base64 encoded digest of X.509
    SubjectPublicKeyInfo (SPKI)</pin>
מאפיינים:
digest
אלגוריתם התקציר ששימש ליצירת הסיכה. בשלב זה יש תמיכה רק ב-"SHA-256".

מקורות מידע נוספים

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

Codelabs