بهبود امنیت برنامه

با ایمن‌تر کردن برنامه‌تان، به حفظ اعتماد کاربر و تمامیت دستگاه کمک می‌کنید.

این صفحه چندین روال مطلوب را ارائه می‌دهد که تأثیر مثبت و قابل‌توجهی بر امنیت برنامه‌تان دارد.

اجرای ارتباط امن

وقتی از داده‌هایی که بین برنامه‌تان و برنامه‌های دیگر یا بین برنامه‌تان و وب‌سایت ردوبدل می‌کنید محافظت کنید، پایداری برنامه‌تان را بهبود می‌بخشید و از داده‌هایی که ارسال و دریافت می‌کنید محافظت می‌کنید.

محافظت از ارتباط بین برنامه‌ها

برای برقراری ارتباط ایمن‌تر بین برنامه‌ها، از هدف‌های ضمنی با انتخابگر برنامه، اجازه‌های مبتنی بر امضا، و ارائه‌دهندگان محتوای صادرنشده استفاده کنید.

نمایش انتخاب‌گر برنامه

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

کاتلین

val intent = Intent(Intent.ACTION_SEND)
val possibleActivitiesList: List<ResolveInfo> =
        packageManager.queryIntentActivities(intent, PackageManager.MATCH_ALL)

// Verify that an activity in at least two apps on the user's device
// can handle the intent. Otherwise, start the intent only if an app
// on the user's device can handle the intent.
if (possibleActivitiesList.size > 1) {

    // Create intent to show chooser.
    // Title is something similar to "Share this photo with."

    <b>val chooser = resources.getString(R.string.chooser_title).let { title ->
        Intent.createChooser(intent, title)
    }
    startActivity(chooser)</b>
} else if (intent.resolveActivity(packageManager) != null) {
    startActivity(intent)
}

جاوا

Intent intent = new Intent(Intent.ACTION_SEND);
List&lt;ResolveInfo&gt; possibleActivitiesList = getPackageManager()
        .queryIntentActivities(intent, PackageManager.MATCH_ALL);

// Verify that an activity in at least two apps on the user's device
// can handle the intent. Otherwise, start the intent only if an app
// on the user's device can handle the intent.
if (possibleActivitiesList.size() > 1) {

    // Create intent to show chooser.
    // Title is something similar to "Share this photo with."

    <b>String title = getResources().getString(R.string.chooser_title);
    Intent chooser = Intent.createChooser(intent, title);
    startActivity(chooser);</b>
} else if (intent.resolveActivity(getPackageManager()) != null) {
    startActivity(intent);
}

اطلاعات مرتبط:

اعمال اجازه‌های مبتنی بر امضا

هنگام هم‌رسانی داده‌ها بین دو برنامه‌ای که کنترل یا مالکیت آن‌ها را برعهده دارید، از اجازه‌های مبتنی بر امضا استفاده کنید. این اجازه‌ها به تأیید کاربر نیاز ندارند و درعوض بررسی می‌کنند که برنامه‌هایی که به داده‌ها دسترسی دارند بااستفاده از همان کلید امضا امضا شده باشند. بنابراین، این اجازه‌ها تجربه کاربری ساده‌تر و ایمن‌تری ارائه می‌دهند.

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.myapp">
    <permission android:name="my_custom_permission_name"
                android:protectionLevel="signature" />

اطلاعات مرتبط:

دسترسی به ارائه‌دهندگان محتوای برنامه‌تان را غیرمجاز کنید

مگراینکه قصد داشته باشید داده‌ها را از برنامه‌تان به برنامه دیگری که متعلق به شما نیست ارسال کنید، صریحاً به برنامه‌های توسعه‌دهندگان دیگر اجازه ندهید به اشیاء ContentProvider برنامه‌تان دسترسی داشته باشند. این تنظیم به‌ویژه اگر برنامه‌تان بتواند در دستگاه‌های دارای Android 4.1.1 (سطح میانای برنامه‌سازی کاربردی ۱۶) یا پایین‌تر نصب شود مهم است، زیرا مشخصه android:exported عنصر <provider> به‌طور پیش‌فرض در آن نسخه‌های Android true است.

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.myapp">
    <application ... >
        <provider
            android:name="androidx.core.content.FileProvider"
            android:authorities="com.example.myapp.fileprovider"
            ...
            android:exported="false">
            <!-- Place child elements of <provider> here. -->
        </provider>
        ...
    </application>
</manifest>

قبل‌از نمایش اطلاعات حساس، اطلاعات کاربری درخواست شود

هنگام درخواست اطلاعات اعتباری از کاربران برای دسترسی به اطلاعات حساس یا محتوای پولی در برنامه‌تان، پین/گذرواژه/الگو یا اطلاعات اعتباری زیست‌سنجشی مانند تشخیص چهره یا تشخیص اثر انگشت را درخواست کنید.

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

اعمال اقدامات امنیتی شبکه

بخش‌های زیر توضیح می‌دهند که چگونه می‌توانید امنیت شبکه برنامه‌تان را بهبود بخشید.

استفاده از ترافیک TLS

اگر برنامه‌تان با سرور وبی ارتباط برقرار می‌کند که گواهی صادرشده توسط مرجع صدور گواهی (CA) معتبر و شناخته‌شده‌ای دارد، از درخواست HTTPS مانند زیر استفاده کنید:

کاتلین

val url = URL("https://www.google.com")
val urlConnection = url.openConnection() as HttpsURLConnection
urlConnection.connect()
urlConnection.inputStream.use {
    ...
}

جاوا

URL url = new URL("https://www.google.com");
HttpsURLConnection urlConnection = (HttpsURLConnection) url.openConnection();
urlConnection.connect();
InputStream in = urlConnection.getInputStream();

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

اگر برنامه‌تان از CA جدید یا سفارشی استفاده می‌کند، می‌توانید تنظیمات امنیتی شبکه‌تان را در فایل پیکربندی اعلام کنید. این فرایند به شما امکان می‌دهد پیکربندی را بدون تغییر دادن کد برنامه ایجاد کنید.

برای افزودن فایل پیکربندی امنیت شبکه به برنامه‌تان، این مراحل را دنبال کنید:

  1. پیکربندی را در مانیفست برنامه‌تان اعلام کنید:
  2. <manifest ... >
        <application
            android:networkSecurityConfig="@xml/network_security_config"
            ... >
            <!-- Place child elements of <application> element here. -->
        </application>
    </manifest>
  3. فایل منبع XML را که در res/xml/network_security_config.xml قرار دارد اضافه کنید.

    با غیرفعال کردن متن واضح، مشخص کنید که همه ترافیک به دامنه‌های خاص باید از HTTPS استفاده کند:

    <network-security-config>
        <domain-config cleartextTrafficPermitted="false">
            <domain includeSubdomains="true">secure.example.com</domain>
            ...
        </domain-config>
    </network-security-config>

    درطول فرایند توسعه، می‌توانید از عنصر <debug-overrides> برای اجازه دادن صریح به گواهی‌های نصب‌شده توسط کاربر استفاده کنید. این عنصر گزینه‌های مهم امنیتی برنامه‌تان را درطول اشکال‌زدایی و آزمایش لغو می‌کند، بدون اینکه بر پیکربندی انتشار برنامه تأثیر بگذارد. تکه‌کد زیر نشان می‌دهد که چگونه این عنصر را در فایل XML پیکربندی امنیت شبکه برنامه‌تان تعریف کنید:

    <network-security-config>
        <debug-overrides>
            <trust-anchors>
                <certificates src="user" />
            </trust-anchors>
        </debug-overrides>
    </network-security-config>

اطلاعات مرتبط: پیکربندی امنیت شبکه

مدیر اعتماد خودتان را ایجاد کنید

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

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

برای کسب اطلاعات بیشتر درباره نحوه تکمیل این مراحل، به بحث مربوط به رسیدگی به مرجع صدور گواهی ناشناخته مراجعه کنید.

اطلاعات مرتبط:

از اشیای WebView با دقت استفاده کنید

WebView شیء در برنامه‌تان نباید به کاربران اجازه دهد به سایت‌هایی که خارج از کنترل شما هستند پیمایش کنند. هرزمان ممکن بود، از فهرست مجاز برای محدود کردن محتوای بارشده توسط اشیاء WebView برنامه‌تان استفاده کنید.

علاوه‌براین، هرگز پشتیبانی از میانای جاوا اسکریپت را فعال نکنید، مگراینکه کاملاً بر محتوای موجود در اشیای WebView برنامه‌تان کنترل داشته باشید و به آن اعتماد داشته باشید.

استفاده از کانال‌های پیام HTML

اگر برنامه‌تان باید از پشتیبانی میانای JavaScript در دستگاه‌های دارای Android نسخه 6.0 (سطح میانای برنامه‌سازی کاربردی ۲۳) و بالاتر استفاده کند، به‌جای برقراری ارتباط بین وب‌سایت و برنامه‌تان، از کانال‌های پیام HTML استفاده کنید، همان‌طور که در تکه‌کد زیر نشان داده شده است:

کاتلین

val myWebView: WebView = findViewById(R.id.webview)

// channel[0] and channel[1] represent the two ports.
// They are already entangled with each other and have been started.
val channel: Array&lt;out WebMessagePort&gt; = myWebView.createWebMessageChannel()

// Create handler for channel[0] to receive messages.
channel[0].setWebMessageCallback(object : WebMessagePort.WebMessageCallback() {

    override fun onMessage(port: WebMessagePort, message: WebMessage) {
        Log.d(TAG, "On port $port, received this message: $message")
    }
})

// Send a message from channel[1] to channel[0].
channel[1].postMessage(WebMessage("My secure message"))

جاوا

WebView myWebView = (WebView) findViewById(R.id.webview);

// channel[0] and channel[1] represent the two ports.
// They are already entangled with each other and have been started.
WebMessagePort[] channel = myWebView.createWebMessageChannel();

// Create handler for channel[0] to receive messages.
channel[0].setWebMessageCallback(new WebMessagePort.WebMessageCallback() {
    @Override
    public void onMessage(WebMessagePort port, WebMessage message) {
         Log.d(TAG, "On port " + port + ", received this message: " + message);
    }
});

// Send a message from channel[1] to channel[0].
channel[1].postMessage(new WebMessage("My secure message"));

اطلاعات مرتبط:

اجازه‌های مناسب را اعطا کنید

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

استفاده از قصدها برای به‌تعویق انداختن اجازه‌ها

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

مثال زیر نشان می‌دهد که چگونه می‌توان از یک قصد برای هدایت کاربران به یک برنامه مخاطبین استفاده کرد، به‌جای اینکه درخواست READ_CONTACTS و WRITE_CONTACTS اجازه‌ها را داد:

کاتلین

// Delegates the responsibility of creating the contact to a contacts app,
// which has already been granted the appropriate WRITE_CONTACTS permission.
Intent(Intent.ACTION_INSERT).apply {
    type = ContactsContract.Contacts.CONTENT_TYPE
}.also { intent ->
    // Make sure that the user has a contacts app installed on their device.
    intent.resolveActivity(packageManager)?.run {
        startActivity(intent)
    }
}

جاوا

// Delegates the responsibility of creating the contact to a contacts app,
// which has already been granted the appropriate WRITE_CONTACTS permission.
Intent insertContactIntent = new Intent(Intent.ACTION_INSERT);
insertContactIntent.setType(ContactsContract.Contacts.CONTENT_TYPE);

// Make sure that the user has a contacts app installed on their device.
if (insertContactIntent.resolveActivity(getPackageManager()) != null) {
    startActivity(insertContactIntent);
}

علاوه‌براین، اگر برنامه‌تان نیاز به انجام ورودی/خروجی مبتنی بر فایل دارد (مثلاً دسترسی به فضای ذخیره‌سازی یا انتخاب فایل)، به اجازه‌های ویژه نیاز ندارد زیرا سیستم می‌تواند این عملیات را ازطرف برنامه‌تان تکمیل کند. بهتر از آن، پس‌از اینکه کاربر محتوایی را در یک URI خاص انتخاب می‌کند، به برنامه تماس‌گیرنده اجازه دسترسی به منبع انتخاب‌شده اعطا می‌شود.

اطلاعات مرتبط:

هم‌رسانی ایمن داده‌ها در برنامه‌ها

برای هم‌رسانی محتوای برنامه‌تان با برنامه‌های دیگر به‌شیوه‌ای ایمن‌تر، این روال‌های مطلوب را دنبال کنید:

  • درصورت نیاز، اجازه‌های فقط خواندنی یا فقط نوشتنی را اعمال کنید.
  • بااستفاده از پرچم‌های FLAG_GRANT_READ_URI_PERMISSION و FLAG_GRANT_WRITE_URI_PERMISSION، دسترسی یک‌باره به داده‌ها را برای کارخواه‌ها فراهم کنید.
  • هنگام هم‌رسانی داده‌ها، از شناسه منبع یکسان content:// استفاده کنید، نه شناسه منبع یکسان file://. نمونه‌های FileProvider این کار را برایتان انجام می‌دهند.

تکه‌کد زیر نشان می‌دهد که چگونه می‌توان از پرچم‌های اعطای اجازه URI و اجازه‌های ارائه‌دهنده محتوا برای نمایش فایل PDF برنامه در برنامه نمایشگر PDF جداگانه استفاده کرد:

کاتلین

// Create an Intent to launch a PDF viewer for a file owned by this app.
Intent(Intent.ACTION_VIEW).apply {
    data = Uri.parse("<b>content:</b>//com.example/personal-info.pdf")

    // This flag gives the started app read access to the file.
    <b>addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)</b>
}.also { intent ->
    // Make sure that the user has a PDF viewer app installed on their device.
    intent.resolveActivity(packageManager)?.run {
        startActivity(intent)
    }
}

جاوا

// Create an Intent to launch a PDF viewer for a file owned by this app.
Intent viewPdfIntent = new Intent(Intent.ACTION_VIEW);
viewPdfIntent.setData(Uri.parse("<b>content://</b>com.example/personal-info.pdf"));

// This flag gives the started app read access to the file.
<b>viewPdfIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);</b>

// Make sure that the user has a PDF viewer app installed on their device.
if (viewPdfIntent.resolveActivity(getPackageManager()) != null) {
    startActivity(viewPdfIntent);
}

توجه: اجرای فایل‌ها از دایرکتوری صفحه اصلی برنامه قابل‌نوشتن، نقض W^X است. به همین دلیل، برنامه‌های غیرقابل‌اعتماد که Android 10 (سطح میانای برنامه‌سازی کاربردی ۲۹) و بالاتر را هدف قرار می‌دهند نمی‌توانند exec() را در فایل‌های موجود در دایرکتوری اصلی برنامه فراخوانی کنند، فقط کد دودویی که در فایل APK برنامه جاسازی شده است. علاوه‌براین، برنامه‌هایی که Android 10 و بالاتر را هدف قرار می‌دهند نمی‌توانند، در حافظه، کد اجرایی را از فایل‌هایی که با dlopen() باز شده‌اند اصلاح کنند. این شامل هر فایل شیء هم‌رسانی‌شده (.so) با جابه‌جایی نوشتار می‌شود.

اطلاعات مرتبط: android:grantUriPermissions

ذخیره ایمن داده‌ها

اگرچه ممکن است برنامه شما به دسترسی به اطلاعات حساس کاربر نیاز داشته باشد، کاربران تنها درصورتی به برنامه شما اجازه دسترسی به داده‌هایشان را می‌دهند که مطمئن باشند به‌درستی از آن محافظت می‌کنید.

ذخیره کردن داده‌های خصوصی در فضای ذخیره‌سازی داخلی

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

تکه‌کد زیر یکی از روش‌های نوشتن داده در فضای ذخیره‌سازی داخلی را نشان می‌دهد:

کاتلین

// Creates a file with this name, or replaces an existing file
// that has the same name. Note that the file name cannot contain
// path separators.
val FILE_NAME = "sensitive_info.txt"
val fileContents = "This is some top-secret information!"
File(filesDir, FILE_NAME).bufferedWriter().use { writer ->
    writer.write(fileContents)
}

جاوا

// Creates a file with this name, or replaces an existing file
// that has the same name. Note that the file name cannot contain
// path separators.
final String FILE_NAME = "sensitive_info.txt";
String fileContents = "This is some top-secret information!";
try (BufferedWriter writer =
             new BufferedWriter(new FileWriter(new File(getFilesDir(), FILE_NAME)))) {
    writer.write(fileContents);
} catch (IOException e) {
    // Handle exception.
}

تکه‌کد زیر عملیات معکوس را نشان می‌دهد، خواندن داده‌ها از فضای ذخیره‌سازی داخلی:

کاتلین

val FILE_NAME = "sensitive_info.txt"
val contents = File(filesDir, FILE_NAME).bufferedReader().useLines { lines ->
    lines.fold("") { working, line ->
        "$working\n$line"
    }
}

جاوا

final String FILE_NAME = "sensitive_info.txt";
StringBuffer stringBuffer = new StringBuffer();
try (BufferedReader reader =
             new BufferedReader(new FileReader(new File(getFilesDir(), FILE_NAME)))) {

    String line = reader.readLine();
    while (line != null) {
        stringBuffer.append(line).append('\n');
        line = reader.readLine();
    }
} catch (IOException e) {
    // Handle exception.
}

اطلاعات مرتبط:

ذخیره داده‌ها در فضای ذخیره‌سازی خارجی براساس مورد استفاده

از فضای ذخیره‌سازی خارجی برای فایل‌های بزرگ و غیرحساسی که مختص برنامه‌تان هستند و همچنین فایل‌هایی که برنامه‌تان با برنامه‌های دیگر هم‌رسانی می‌کند استفاده کنید. میاناهای برنامه‌سازی کاربردی خاصی که استفاده می‌کنید به این بستگی دارد که برنامه‌تان برای دسترسی به فایل‌های مختص برنامه طراحی شده است یا دسترسی به فایل‌های مشترک.

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

اگر برنامه‌تان نیاز دارد به فایلی دسترسی داشته باشد یا آن را ذخیره کند که برای برنامه‌های دیگر مفید است، بسته به مورد استفاده‌تان، از یکی از میاناهای برنامه‌سازی کاربردی زیر استفاده کنید:

  • فایل‌های رسانه‌ای: برای ذخیره و دسترسی به تصاویر، فایل‌های صوتی، و ویدیوهایی که بین برنامه‌ها هم‌رسانی می‌شوند، از Media Store API استفاده کنید.
  • فایل‌های دیگر: برای ذخیره کردن و دسترسی به انواع دیگر فایل‌های هم‌رسانی‌شده، ازجمله فایل‌های بارگیری‌شده، از Storage Access Framework استفاده کنید.

بررسی دردسترس بودن حجم فضای ذخیره‌سازی

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

بررسی اعتبار داده‌ها

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

تکه‌کد زیر شامل نمونه‌ای از درستی‌سنج درهم‌ساز است:

کاتلین

val hash = calculateHash(stream)
// Store "expectedHash" in a secure location.
if (hash == <var>expectedHash</var>) {
    // Work with the content.
}

// Calculating the hash code can take quite a bit of time, so it shouldn't
// be done on the main thread.
suspend fun calculateHash(stream: InputStream): String {
    return withContext(Dispatchers.IO) {
        val digest = MessageDigest.getInstance("SHA-512")
        val digestStream = DigestInputStream(stream, digest)
        while (digestStream.read() != -1) {
            // The DigestInputStream does the work; nothing for us to do.
        }
        digest.digest().joinToString(":") { "%02x".format(it) }
    }
}

جاوا

Executor threadPoolExecutor = Executors.newFixedThreadPool(4);
private interface HashCallback {
    void onHashCalculated(@Nullable String hash);
}

boolean hashRunning = calculateHash(inputStream, threadPoolExecutor, hash -&gt; {
    if (Objects.equals(hash, <var>expectedHash</var>)) {
        // Work with the content.
    }
});

if (!hashRunning) {
    // There was an error setting up the hash function.
}

private boolean calculateHash(@NonNull InputStream stream,
                              @NonNull Executor executor,
                              @NonNull HashCallback hashCallback) {
    final MessageDigest digest;
    try {
        digest = MessageDigest.getInstance("SHA-512");
    } catch (NoSuchAlgorithmException nsa) {
        return false;
    }

    // Calculating the hash code can take quite a bit of time, so it shouldn't
    // be done on the main thread.
    executor.execute(() -&gt; {
        String hash;
        try (DigestInputStream digestStream =
                new DigestInputStream(stream, digest)) {
            while (digestStream.read() != -1) {
                // The DigestInputStream does the work; nothing for us to do.
            }
            StringBuilder builder = new StringBuilder();
            for (byte aByte : digest.digest()) {
                builder.append(String.format("%02x", aByte)).append(':');
            }
            hash = builder.substring(0, builder.length() - 1);
        } catch (IOException e) {
            hash = null;
        }

        final String calculatedHash = hash;
        runOnUiThread(() -> hashCallback.onHashCalculated(calculatedHash));
    });
    return true;
}

استفاده از فضای ذخیره‌سازی داخلی برای داده‌های حساس حافظه پنهان

برای دسترسی سریع‌تر به داده‌های برنامه، آن را در حافظه نهان دستگاه ذخیره کنید. برای حافظه‌های نهان ۱ مگابایتی یا کوچک‌تر، از getCacheDir() استفاده کنید. برای حافظه‌های پنهان بزرگ‌تر از ۱ مگابایت، از getExternalCacheDir() استفاده کنید. هر دو روش شیء File را که حاوی داده‌های ذخیره‌شده در حافظه نهان برنامه‌تان است دراختیارتان قرار می‌دهد.

درحالی‌که فهرست راهنمای حافظه نهان داخلی (ارائه‌شده توسط getCacheDir()) برای برنامه شما خصوصی است، فهرست راهنمای حافظه نهان خارجی خصوصی نیست.

تکه‌کد زیر نحوه ذخیره کردن فایلی را که برنامه‌تان اخیراً بارگیری کرده است در حافظه نهان نشان می‌دهد:

کاتلین

val cacheFile = File(myDownloadedFileUri).let { fileToCache ->
    File(cacheDir.path, fileToCache.name)
}

جاوا

File cacheDir = getCacheDir();
File fileToCache = new File(myDownloadedFileUri);
String fileToCacheName = fileToCache.getName();
File cacheFile = new File(cacheDir.getPath(), fileToCacheName);

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

احتیاط: هیچ امنیتی برای فایل‌ها در فهرست راهنمای حافظه نهان خارجی اعمال نمی‌شود. بنابراین، هر برنامه‌ای که Android 10 (سطح میانای برنامه‌سازی کاربردی ۲۹) یا پایین‌تر را هدف قرار دهد و اجازه WRITE_EXTERNAL_STORAGE را داشته باشد می‌تواند به محتوای این حافظه نهان دسترسی پیدا کند.

اطلاعات مرتبط: نمای کلی فضای ذخیره‌سازی داده و فایل

استفاده از SharedPreferences در حالت خصوصی

هنگام استفاده از getSharedPreferences() برای ایجاد یا دسترسی به اشیای SharedPreferences برنامه‌تان، از MODE_PRIVATE استفاده کنید. به این ترتیب، فقط برنامه شما می‌تواند به اطلاعات موجود در فایل اولویت‌های مشترک دسترسی داشته باشد.

اگر می‌خواهید داده‌ها را بین برنامه‌ها هم‌رسانی کنید، از اشیاء SharedPreferences استفاده نکنید. درعوض، مراحل هم‌رسانی ایمن داده‌ها در برنامه‌ها را دنبال کنید.

اطلاعات مرتبط:

به‌روز نگه داشتن سرویس‌ها و وابستگی‌ها

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

بررسی ارائه‌دهنده امنیتی «خدمات Google Play»

توجه: این بخش فقط برای برنامه‌هایی کاربرد دارد که دستگاه‌های دارای خدمات Google Play را هدف قرار می‌دهند.

اگر برنامه‌تان از خدمات Google Play استفاده می‌کند، مطمئن شوید که این خدمات در دستگاهی که برنامه‌تان نصب شده است به‌روز باشد. بررسی را به‌صورت ناهمگام، خارج از رشته میانای کاربر انجام دهید. اگر دستگاه به‌روز نباشد، خطای صدور مجوز را راه‌اندازی کنید.

برای تعیین اینکه آیا خدمات Google Play در دستگاهی که برنامه‌تان در آن نصب شده است به‌روز است یا نه، مراحل راهنمای مربوط به به‌روزرسانی ارائه‌دهنده امنیتی برای محافظت دربرابر سوءاستفاده‌های SSL را دنبال کنید.

اطلاعات مرتبط:

به‌روزرسانی همه وابستگی‌های برنامه

قبل‌از استقرار برنامه‌تان، مطمئن شوید که همه کتابخانه‌ها، کیت‌های توسعه نرم‌افزار، و سایر وابستگی‌ها به‌روز باشند:

  • برای وابستگی‌های شخص اول، مثل کیت توسعه نرم‌افزار Android، از ابزارهای به‌روزرسانی موجود در Android Studio، مثل مدیر کیت توسعه نرم‌افزار، استفاده کنید.
  • برای وابستگی‌های شخص ثالث، وب‌سایت‌های کتابخانه‌هایی را که برنامه‌تان استفاده می‌کند بررسی کنید و هرگونه به‌روزرسانی و وصله امنیتی دردسترس را نصب کنید.

اطلاعات مرتبط: افزودن وابستگی‌های ساخت

اطلاعات بیشتر

برای کسب اطلاعات بیشتر درباره نحوه ایمن‌تر کردن برنامه‌تان، منابع زیر را مشاهده کنید: