پیکربندی امنیت شبکه

ویژگی Network Security Configuration به شما امکان می دهد تنظیمات امنیتی شبکه برنامه خود را در یک فایل پیکربندی ایمن و شفاف بدون تغییر کد برنامه سفارشی کنید. این تنظیمات را می توان برای دامنه های خاص و برای یک برنامه خاص پیکربندی کرد. قابلیت های کلیدی این ویژگی عبارتند از:

  • لنگرهای اعتماد سفارشی: سفارشی کنید که کدام مقامات گواهی (CA) برای اتصالات امن برنامه مورد اعتماد هستند. برای مثال، اعتماد به گواهی‌های خاص خودامضا یا محدود کردن مجموعه‌ای از CA عمومی که برنامه به آنها اعتماد دارد.
  • لغو فقط اشکال زدایی: اتصالات ایمن را در یک برنامه بدون خطر اضافی برای پایه نصب شده اشکال زدایی کنید.
  • انصراف از ترافیک Cleartext: از برنامه ها در برابر استفاده تصادفی از ترافیک متن شفاف (رمزگذاری نشده) محافظت کنید.
  • پین کردن گواهی: اتصال امن برنامه را به گواهی‌های خاص محدود کنید.

یک فایل پیکربندی امنیت شبکه اضافه کنید

ویژگی پیکربندی امنیت شبکه از یک فایل XML استفاده می کند که در آن تنظیمات برنامه خود را مشخص می کنید. برای اشاره به این فایل باید یک ورودی در مانیفست برنامه خود وارد کنید. گزیده کد زیر از یک مانیفست نحوه ایجاد این ورودی را نشان می دهد:

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

CA های مورد اعتماد را سفارشی کنید

ممکن است بخواهید برنامه شما به جای پیش‌فرض پلتفرم، به مجموعه‌ای از CA سفارشی اعتماد کند. شایع ترین دلایل این امر عبارتند از:

  • اتصال به یک میزبان با یک CA سفارشی، مانند یک CA که خودامضا شده یا در داخل یک شرکت صادر شده است.
  • محدود کردن مجموعه CA به جای هر CA از پیش نصب شده، فقط به CAهایی که به آنها اعتماد دارید.
  • اعتماد به CA های اضافی که در سیستم گنجانده نشده اند.

به طور پیش‌فرض، اتصالات امن (با استفاده از پروتکل‌هایی مانند TLS و HTTPS) از همه برنامه‌ها به CA سیستم از پیش نصب‌شده و برنامه‌هایی که Android 6.0 (سطح API 23) و پایین‌تر را هدف قرار می‌دهند نیز به‌طور پیش‌فرض به فروشگاه CA اضافه‌شده توسط کاربر اعتماد دارند. می توانید اتصالات برنامه خود را با استفاده از base-config (برای سفارشی سازی در سطح برنامه) یا domain-config (برای سفارشی سازی هر دامنه) سفارشی کنید.

یک CA سفارشی را پیکربندی کنید

ممکن است بخواهید به میزبانی متصل شوید که از گواهینامه SSL با امضای خود استفاده می کند یا به میزبانی که گواهی SSL آن توسط یک CA غیرعمومی مورد اعتماد شما صادر شده است، مانند CA داخلی شرکت شما. گزیده کد زیر نحوه پیکربندی برنامه خود را برای یک 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های مورد اعتماد را مشخص کنید. این برنامه را در برابر گواهی های تقلبی صادر شده توسط هر یک از CA های دیگر محافظت می کند.

پیکربندی برای محدود کردن مجموعه 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>

CAهای مورد اعتماد را در قالب PEM یا DER به res/raw/trusted_roots اضافه کنید. توجه داشته باشید که اگر از فرمت PEM استفاده می کنید، فایل باید فقط حاوی داده های PEM و بدون متن اضافی باشد. شما همچنین می توانید چندین عنصر <certificates> را به جای یک عنصر ارائه دهید.

به CA های اضافی اعتماد کنید

ممکن است بخواهید برنامه شما به CA های دیگری که مورد اعتماد سیستم نیستند اعتماد کند، مثلاً اگر سیستم هنوز شامل CA نیست یا CA شرایط لازم برای گنجاندن در سیستم 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 . به طور معمول، IDE ها و ابزارهای ساخت، این پرچم را به طور خودکار برای ساخت های غیر انتشار تنظیم می کنند.

این از کد مشروط معمولی ایمن تر است زیرا به عنوان یک اقدام احتیاطی امنیتی، فروشگاه های برنامه برنامه هایی را که قابل اشکال زدایی علامت گذاری شده اند نمی پذیرند.

گزیده زیر نحوه تعیین CA های فقط اشکال زدایی را در 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 8.1 (سطح API 27) یا پایین‌تر را هدف قرار می‌دهند. با شروع اندروید 9 (سطح 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>

گواهینامه ها را پین کنید

به طور معمول، یک برنامه به همه CA های از پیش نصب شده اعتماد دارد. اگر هر یک از این CA ها گواهی تقلبی صادر کنند، برنامه در معرض خطر یک مهاجم در مسیر قرار می گیرد. برخی از برنامه‌ها انتخاب می‌کنند که مجموعه گواهی‌هایی را که می‌پذیرند با محدود کردن مجموعه‌ای از CA مورد اعتمادشان یا با پین کردن گواهی محدود کنند.

پین کردن گواهی با ارائه مجموعه ای از گواهی ها توسط هش کلید عمومی ( SubjectPublicKeyInfo از گواهی X.509) انجام می شود. یک زنجیره گواهی تنها در صورتی معتبر است که زنجیره گواهی شامل حداقل یکی از کلیدهای عمومی پین شده باشد.

توجه داشته باشید که هنگام استفاده از پین کردن گواهی، همیشه باید یک کلید پشتیبان اضافه کنید تا اگر مجبور شدید به کلیدهای جدید بروید یا CA را تغییر دهید (هنگام پین کردن به گواهی CA یا واسطه آن 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>
        <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 باید از یک مجموعه سفارشی از CA استفاده کنند. علاوه بر این، ترافیک متن شفاف به این دامنه‌ها مجاز است ، مگر زمانی که به 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>
توضیحات:
پیکربندی پیش‌فرض مورد استفاده همه اتصالاتی که مقصد آنها توسط یک domain-config پوشش داده نمی‌شود.

هر مقداری که تنظیم نشده باشد از مقادیر پیش‌فرض پلتفرم استفاده می‌کند.

پیکربندی پیش‌فرض برای برنامه‌هایی که اندروید 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>

پیکربندی پیش‌فرض برای برنامه‌هایی که اندروید 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>
می تواند شامل:
1 یا بیشتر <domain>
0 یا 1 <trust-anchors>
0 یا 1 <pin-set>
هر تعداد <domain-config> تودرتو
توضیحات:
پیکربندی مورد استفاده برای اتصال به مقاصد خاص، همانطور که توسط عناصر domain تعریف شده است.

توجه داشته باشید که اگر چندین عنصر domain-config یک مقصد را پوشش دهند، از پیکربندی با خاص ترین (طولانی ترین) قانون دامنه منطبق استفاده می شود.

<دامنه>

نحو:
<domain includeSubdomains=["true" | "false"]>example.com</domain>
صفات:
includeSubdomains
اگر "true" باشد، این قانون دامنه با دامنه و همه زیر دامنه ها، از جمله زیر دامنه های زیر دامنه ها مطابقت دارد. در غیر این صورت، این قانون فقط برای تطابق دقیق اعمال می شود.

<debug-overrides>

نحو:
<debug-overrides>
    ...
</debug-overrides>
می تواند شامل:
0 یا 1 <trust-anchors>
توضیحات:
لغو زمانی که android:debuggable "true" باشد اعمال می‌شود، که معمولاً برای ساخت‌های غیرانتشاری تولید شده توسط IDEها و ابزارهای ساخت، صادق است. لنگرهای اعتماد مشخص شده در debug-overrides به همه پیکربندی‌های دیگر اضافه می‌شوند و زمانی که زنجیره گواهی سرور از یکی از این لنگرهای اعتماد فقط اشکال‌زدایی استفاده می‌کند، پین کردن گواهی انجام نمی‌شود. اگر android:debuggable "false" باشد، این بخش کاملا نادیده گرفته می شود.

<trust-anchors>

نحو:
<trust-anchors>
...
</trust-anchors>
می تواند شامل:
هر تعداد <certificates>
توضیحات:
مجموعه ای از لنگرهای اعتماد برای اتصالات ایمن.

<گواهی نامه ها>

نحو:
<certificates src=["system" | "user" | "raw resource"]
              overridePins=["true" | "false"] />
توضیحات:
مجموعه ای از گواهینامه های X.509 برای عناصر trust-anchors .
صفات:
src
منبع گواهینامه های CA. هر گواهی می تواند یکی از موارد زیر باشد:
  • یک شناسه منبع خام که به فایلی حاوی گواهینامه های X.509 اشاره می کند. گواهینامه ها باید با فرمت DER یا PEM کدگذاری شوند. در مورد گواهی‌های PEM، فایل نباید حاوی داده‌های غیر PEM اضافی مانند نظرات باشد.
  • "system" برای گواهینامه های CA سیستم از پیش نصب شده
  • "user" برای گواهی های CA اضافه شده توسط کاربر
overridePins

مشخص می کند که آیا CAهای این منبع از پین کردن گواهی عبور می کنند یا خیر. اگر "true" ، پین کردن در زنجیره های گواهی که توسط یکی از CA از این منبع امضا شده است انجام نمی شود. این می‌تواند برای اشکال‌زدایی CA یا آزمایش حملات Man-in-the-Middle بر روی ترافیک امن برنامه شما مفید باشد.

پیش‌فرض "false" است، مگر اینکه در عنصر debug-overrides مشخص شده باشد، در این صورت پیش‌فرض "true" است.

<pin-set>

نحو:
<pin-set expiration="date">
...
</pin-set>
می تواند شامل:
هر تعداد <pin>
توضیحات:
مجموعه ای از پین های کلید عمومی برای اینکه یک اتصال امن قابل اعتماد باشد، یکی از کلیدهای عمومی در زنجیره اعتماد باید در مجموعه پین ​​ها باشد. برای فرمت پین ها به <pin> مراجعه کنید.
صفات:
expiration
تاریخ، در قالب yyyy-MM-dd که در آن پین ها منقضی می شوند، بنابراین پین کردن غیرفعال می شود. اگر ویژگی تنظیم نشده باشد، پین ها منقضی نمی شوند.

انقضا به جلوگیری از مشکلات اتصال در برنامه‌هایی که به‌روزرسانی‌های مجموعه پین ​​خود را دریافت نمی‌کنند، مانند زمانی که کاربر به‌روزرسانی‌های برنامه را غیرفعال می‌کند، کمک می‌کند.

<پین>

نحو:
<pin digest=["SHA-256"]>base64 encoded digest of X.509
    SubjectPublicKeyInfo (SPKI)</pin>
صفات:
digest
الگوریتم هضم مورد استفاده برای تولید پین. در حال حاضر، فقط "SHA-256" پشتیبانی می شود.

منابع اضافی

برای اطلاعات بیشتر در مورد پیکربندی امنیت شبکه، به منابع زیر مراجعه کنید.

Codelabs