अपने ऐप्लिकेशन की सुरक्षा को बेहतर बनाएं

अपने ऐप्लिकेशन को ज़्यादा सुरक्षित बनाकर, उपयोगकर्ताओं का भरोसा और डिवाइस की इंटिग्रिटी को बनाए रखने में मदद मिलती है.

इस पेज पर, सबसे सही तरीके बताए गए हैं. इनका इस्तेमाल करके, अपने ऐप्लिकेशन की सुरक्षा को काफ़ी हद तक बेहतर बनाया जा सकता है.

सुरक्षित तरीके से बातचीत करने की सुविधा लागू करना

अपने ऐप्लिकेशन और अन्य ऐप्लिकेशन के बीच या अपने ऐप्लिकेशन और किसी वेबसाइट के बीच शेयर किए जाने वाले डेटा को सुरक्षित रखने से, आपके ऐप्लिकेशन की परफ़ॉर्मेंस बेहतर होती है. साथ ही, भेजे और पाए जाने वाले डेटा को सुरक्षित रखने में मदद मिलती है.

ऐप्लिकेशन के बीच होने वाले कम्यूनिकेशन को सुरक्षित रखना

ऐप्लिकेशन के बीच ज़्यादा सुरक्षित तरीके से कम्यूनिकेट करने के लिए, इंप्लिसिट इंटेंट का इस्तेमाल करें. इसके लिए, ऐप्लिकेशन चुनने वाले टूल, सिग्नेचर पर आधारित अनुमतियों, और एक्सपोर्ट न किए गए कॉन्टेंट देने वाले टूल का इस्तेमाल करें.

ऐप्लिकेशन चुनने वाला डायलॉग बॉक्स दिखाना

अगर कोई इंप्लिसिट इंटेंट, उपयोगकर्ता के डिवाइस पर कम से कम दो संभावित ऐप्लिकेशन लॉन्च कर सकता है, तो ऐप्लिकेशन चुनने वाला विकल्प साफ़ तौर पर दिखाएं. इंटरैक्शन की इस रणनीति से, उपयोगकर्ता अपनी संवेदनशील जानकारी को किसी ऐसे ऐप्लिकेशन पर ट्रांसफ़र कर सकते हैं जिस पर वे भरोसा करते हैं.

Kotlin

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 (possibleActivitiesLi>st.size  1) {

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

    bval chooser = resources.getString(R.string.chooser_ti>tle).let { title -
        Intent.createChooser(intent, title)
    }
    star<tA>ctivity(chooser)/b
} else if (intent.resolveActivity(packageManager) != null) {
    startActivity(intent)
}

Java

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."

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

इससे जुड़ी जानकारी:

सिग्नेचर पर आधारित अनुमतियां लागू करना

आपके मालिकाना हक वाले या आपके कंट्रोल में मौजूद दो ऐप्लिकेशन के बीच डेटा शेयर करते समय, सिग्नेचर पर आधारित अनुमतियों का इस्तेमाल करें. इन अनुमतियों के लिए, उपयोगकर्ता की पुष्टि की ज़रूरत नहीं होती. इसके बजाय, यह जांच की जाती है कि डेटा ऐक्सेस करने वाले ऐप्लिकेशन, एक ही साइनिंग पासकोड का इस्तेमाल करके साइन किए गए हों. इसलिए, ये अनुमतियां उपयोगकर्ताओं को ज़्यादा आसान और सुरक्षित अनुभव देती हैं.

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

मिलती-जुलती जानकारी:

अपने ऐप्लिकेशन के कॉन्टेंट देने वाले को ऐक्सेस करने की अनुमति न देना

जब तक आपको अपने ऐप्लिकेशन से किसी ऐसे ऐप्लिकेशन को डेटा न भेजना हो जिसका मालिकाना हक आपके पास नहीं है, तब तक अन्य डेवलपर के ऐप्लिकेशन को अपने ऐप्लिकेशन के ContentProvider ऑब्जेक्ट ऐक्सेस करने की अनुमति न दें. यह सेटिंग खास तौर पर तब ज़रूरी होती है, जब आपके ऐप्लिकेशन को Android 4.1.1 (एपीआई लेवल 16) या इससे पहले के वर्शन वाले डिवाइसों पर इंस्टॉल किया जा सकता है. ऐसा इसलिए, क्योंकि Android के उन वर्शन पर, <provider> एलिमेंट का android:exported एट्रिब्यूट डिफ़ॉल्ट रूप से true पर सेट होता है.

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com>.exam<ple.myapp"
>    appli<cation ... 
        provider
            android:name="androidx.core.content.FileProvider"
            android:authorities="com.example.myapp.fileprovider"
            >...
         <   android:exported="fa<l>se"
       >     !-- <Place chi>ld elements of pr<ovider here.> <--
      >  /provider
        ...
    /application
/manifest

संवेदनशील जानकारी दिखाने से पहले क्रेडेंशियल मांगना

अपने ऐप्लिकेशन में संवेदनशील जानकारी या प्रीमियम कॉन्टेंट को ऐक्सेस करने के लिए, उपयोगकर्ताओं से क्रेडेंशियल का अनुरोध करते समय, पिन/पासवर्ड/पैटर्न या बायोमेट्रिक क्रेडेंशियल मांगें. जैसे, चेहरे की पहचान या फ़िंगरप्रिंट की पहचान.

बायोमेट्रिक क्रेडेंशियल का अनुरोध करने के तरीके के बारे में ज़्यादा जानने के लिए, बायोमेट्रिक ऑथेंटिकेशन के बारे में गाइड देखें.

नेटवर्क की सुरक्षा के लिए ज़रूरी कदम उठाएं

यहां दिए गए सेक्शन में, अपने ऐप्लिकेशन के नेटवर्क की सुरक्षा को बेहतर बनाने का तरीका बताया गया है.

टीएलएस ट्रैफ़िक का इस्तेमाल करना

अगर आपका ऐप्लिकेशन किसी ऐसे वेब सर्वर से कम्यूनिकेट करता है जिसके पास सर्टिफ़िकेट देने वाली किसी जानी-मानी और भरोसेमंद संस्था (सीए) से जारी किया गया सर्टिफ़िकेट है, तो यहां दिए गए एचटीटीपीएस अनुरोध का इस्तेमाल करें:

Kotlin

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

Java

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

नेटवर्क की सुरक्षा से जुड़ा कॉन्फ़िगरेशन जोड़ना

अगर आपका ऐप्लिकेशन नए या कस्टम सीए का इस्तेमाल करता है, तो कॉन्फ़िगरेशन फ़ाइल में अपने नेटवर्क की सुरक्षा सेटिंग का एलान किया जा सकता है. इस प्रोसेस की मदद से, ऐप्लिकेशन के कोड में बदलाव किए बिना कॉन्फ़िगरेशन बनाया जा सकता है.

अपने ऐप्लिकेशन में नेटवर्क की सुरक्षा से जुड़ी कॉन्फ़िगरेशन फ़ाइल जोड़ने के लिए, यह तरीका अपनाएं:

  1. अपने ऐप्लिकेशन के मेनिफ़ेस्ट में कॉन्फ़िगरेशन का एलान करें:
  2. <manifest ... >
        <application
            android:networkSecurityConfig="@xml/network_security_config"
      >      ...< 
            !-- Place child el<ements of a>pplication elemen>t her<e. --
        /a>p<plication>
    /manifest
  3. res/xml/network_security_config.xml पर मौजूद एक्सएमएल रिसॉर्स फ़ाइल जोड़ें.

    यह तय करें कि कुछ खास डोमेन पर आने वाले सभी ट्रैफ़िक के लिए, एचटीटीपीएस का इस्तेमाल किया जाना चाहिए. इसके लिए, क्लियर-टेक्स्ट को बंद करें:

    <network-security-config>
        <domain-config cleartextTrafficPermitted="f>alse"<;
            domain includeSubdoma>ins="true&quo<t;secur>e.example.com/dom<ain
            ..>.<
        /domain-config
    /net>work-security-config

    डेवलपमेंट प्रोसेस के दौरान, <debug-overrides> एलिमेंट का इस्तेमाल करके, उपयोगकर्ता के इंस्टॉल किए गए सर्टिफ़िकेट को साफ़ तौर पर अनुमति दी जा सकती है. यह एलिमेंट, डीबग करने और टेस्ट करने के दौरान आपके ऐप्लिकेशन के सुरक्षा से जुड़े ज़रूरी विकल्पों को बदल देता है. हालांकि, इससे ऐप्लिकेशन के रिलीज़ कॉन्फ़िगरेशन पर कोई असर नहीं पड़ता. यहां दिए गए स्निपेट में, अपने ऐप्लिकेशन की नेटवर्क सुरक्षा कॉन्फ़िगरेशन एक्सएमएल फ़ाइल में इस एलिमेंट को तय करने का तरीका बताया गया है:

    <network-security-config>
        <debug-overrides>
            <trust-anchors>
                <certificates src="us>er" </
            /tru>st-an<chors
        /debug>-<overrides
    /network-secur>ity-config

इसी विषय से जुड़ी जानकारी: नेटवर्क की सुरक्षा का कॉन्फ़िगरेशन

अपना ट्रस्ट मैनेजर बनाना

आपके टीएलएस चेकर को हर सर्टिफ़िकेट स्वीकार नहीं करना चाहिए. अगर आपके इस्तेमाल के उदाहरण पर इनमें से कोई भी शर्त लागू होती है, तो आपको ट्रस्ट मैनेजर सेट अप करना पड़ सकता है. साथ ही, आपको टीएलएस से जुड़ी सभी चेतावनियों को मैनेज करना पड़ सकता है:

  • आप किसी ऐसे वेब सर्वर से संपर्क कर रहे हैं जिसके सर्टिफ़िकेट पर, किसी नई या कस्टम सीए ने हस्ताक्षर किया है.
  • इस्तेमाल किए जा रहे डिवाइस पर, उस सीए पर भरोसा नहीं किया जाता.
  • नेटवर्क सुरक्षा कॉन्फ़िगरेशन का इस्तेमाल नहीं किया जा सकता.

इन चरणों को पूरा करने के तरीके के बारे में ज़्यादा जानने के लिए, सर्टिफ़िकेट जारी करने वाली किसी अनजान संस्था को मैनेज करने के बारे में दी गई जानकारी देखें.

इससे जुड़ी जानकारी:

WebView ऑब्जेक्ट का इस्तेमाल सावधानी से करना

आपके ऐप्लिकेशन में मौजूद WebView ऑब्जेक्ट, उपयोगकर्ताओं को ऐसी साइटों पर जाने की अनुमति नहीं देते जो आपके कंट्रोल से बाहर हैं. जब भी संभव हो, अनुमति वाली सूची का इस्तेमाल करें. इससे आपके ऐप्लिकेशन के WebView ऑब्जेक्ट से लोड होने वाले कॉन्टेंट को सीमित किया जा सकता है.

इसके अलावा, JavaScript इंटरफ़ेस की सुविधा को तब तक चालू न करें, जब तक आपके पास अपने ऐप्लिकेशन के WebView ऑब्जेक्ट में मौजूद कॉन्टेंट का पूरा कंट्रोल न हो और आपको उस पर पूरा भरोसा न हो.

एचटीएमएल मैसेज चैनलों का इस्तेमाल करना

अगर आपके ऐप्लिकेशन को Android 6.0 (एपीआई लेवल 23) और इसके बाद के वर्शन वाले डिवाइसों पर JavaScript इंटरफ़ेस का इस्तेमाल करना है, तो वेबसाइट और ऐप्लिकेशन के बीच कम्यूनिकेट करने के बजाय, एचटीएमएल मैसेज चैनल का इस्तेमाल करें. इसके लिए, यहां दिए गए कोड स्निपेट का इस्तेमाल करें:

Kotlin

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"))

Java

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(&quot;My secure message"));

इससे जुड़ी जानकारी:

ज़रूरी अनुमतियां देना

अपने ऐप्लिकेशन को ठीक से काम करने के लिए, सिर्फ़ ज़रूरी अनुमतियों का अनुरोध करें. जब आपके ऐप्लिकेशन को अनुमतियों की ज़रूरत न हो, तो उन्हें हटा दें.

अनुमतियों को बाद में लेने के लिए इंटेंट का इस्तेमाल करना

जब भी संभव हो, किसी कार्रवाई को पूरा करने के लिए अपने ऐप्लिकेशन में ऐसी अनुमति न जोड़ें जिसे किसी दूसरे ऐप्लिकेशन में पूरा किया जा सकता है. इसके बजाय, अनुरोध को किसी ऐसे दूसरे ऐप्लिकेशन पर भेजने के लिए इंटेंट का इस्तेमाल करें जिसके पास पहले से ही ज़रूरी अनुमति है.

यहां दिए गए उदाहरण में, इंटेंट का इस्तेमाल करके उपयोगकर्ताओं को संपर्क ऐप्लिकेशन पर भेजने का तरीका बताया गया है. इससे आपको READ_CONTACTS और WRITE_CONTACTS अनुमतियों का अनुरोध करने की ज़रूरत नहीं पड़ती:

Kotlin

// 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)
    }
}

Java

// 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);
}

इसके अलावा, अगर आपके ऐप्लिकेशन को फ़ाइल पर आधारित इनपुट/आउटपुट (I/O) की ज़रूरत है, जैसे कि स्टोरेज को ऐक्सेस करना या कोई फ़ाइल चुनना, तो उसे खास अनुमतियों की ज़रूरत नहीं होती. ऐसा इसलिए, क्योंकि सिस्टम आपके ऐप्लिकेशन की ओर से कार्रवाइयां पूरी कर सकता है. इससे भी बेहतर बात यह है कि जब कोई उपयोगकर्ता किसी यूआरआई पर कॉन्टेंट चुनता है, तो कॉलिंग ऐप्लिकेशन को चुने गए संसाधन की अनुमति मिल जाती है.

इससे जुड़ी जानकारी:

ऐप्लिकेशन के बीच सुरक्षित तरीके से डेटा शेयर करना

अपने ऐप्लिकेशन के कॉन्टेंट को अन्य ऐप्लिकेशन के साथ ज़्यादा सुरक्षित तरीके से शेयर करने के लिए, ये सबसे सही तरीके अपनाएं:

  • ज़रूरत के हिसाब से, रीड-ओनली या राइट-ओनली अनुमतियां लागू करें.
  • FLAG_GRANT_READ_URI_PERMISSION और FLAG_GRANT_WRITE_URI_PERMISSION फ़्लैग का इस्तेमाल करके, क्लाइंट को डेटा का ऐक्सेस सिर्फ़ एक बार दें.
  • डेटा शेयर करते समय, content:// यूआरआई का इस्तेमाल करें, न कि file:// यूआरआई का. FileProvider के इंस्टेंस आपके लिए यह काम करते हैं.

यहां दिए गए कोड स्निपेट में, यूआरआई की अनुमति देने वाले फ़्लैग और कॉन्टेंट देने वाले की अनुमतियों का इस्तेमाल करने का तरीका बताया गया है. इससे किसी ऐप्लिकेशन की PDF फ़ाइल को, PDF व्यूअर वाले किसी अलग ऐप्लिकेशन में दिखाया जा सकता है:

Kotlin

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

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

Java

// 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(&<q>uot;bconte<nt>:///bcom.example/personal-info.pdf"));

// This flag gives the started app read access to <t>he file.
bviewPdfIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PE<RM>ISSION);/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 (एपीआई लेवल 29) और इसके बाद के वर्शन को टारगेट करने वाले ऐसे ऐप्लिकेशन जिन पर भरोसा नहीं किया जा सकता, वे ऐप्लिकेशन की होम डायरेक्ट्री में मौजूद फ़ाइलों पर exec() को लागू नहीं कर सकते. वे सिर्फ़ ऐप्लिकेशन की APK फ़ाइल में एम्बेड किए गए बाइनरी कोड पर इसे लागू कर सकते हैं. इसके अलावा, Android 10 और इसके बाद के वर्शन को टारगेट करने वाले ऐप्लिकेशन, मेमोरी में मौजूद उन फ़ाइलों के एक्ज़ीक्यूटेबल कोड में बदलाव नहीं कर सकते जिन्हें dlopen() की मदद से खोला गया है. इसमें टेक्स्ट रीलोकेशन वाली कोई भी शेयर की गई ऑब्जेक्ट (.so) फ़ाइल शामिल है.

मिलती-जुलती जानकारी: android:grantUriPermissions

डेटा को सुरक्षित तरीके से सेव करना

ऐसा हो सकता है कि आपके ऐप्लिकेशन को उपयोगकर्ता की संवेदनशील जानकारी ऐक्सेस करने की ज़रूरत पड़े. हालांकि, उपयोगकर्ता आपके ऐप्लिकेशन को अपने डेटा का ऐक्सेस सिर्फ़ तब देते हैं, जब उन्हें भरोसा हो कि आप उनके डेटा को सुरक्षित रखेंगे.

निजी डेटा को डिवाइस के स्टोरेज में सेव करना

उपयोगकर्ता का सारा निजी डेटा, डिवाइस के इंटरनल स्टोरेज में सेव करें. यह स्टोरेज, हर ऐप्लिकेशन के लिए सैंडबॉक्स किया जाता है. आपके ऐप्लिकेशन को इन फ़ाइलों को देखने के लिए अनुमति मांगने की ज़रूरत नहीं होती. साथ ही, अन्य ऐप्लिकेशन इन फ़ाइलों को ऐक्सेस नहीं कर सकते. सुरक्षा के लिहाज़ से, जब कोई उपयोगकर्ता किसी ऐप्लिकेशन को अनइंस्टॉल करता है, तो डिवाइस उन सभी फ़ाइलों को मिटा देता है जिन्हें ऐप्लिकेशन ने डिवाइस के स्टोरेज में सेव किया था.

यहां दिए गए कोड स्निपेट में, इंटरनल स्टोरेज में डेटा सेव करने का एक तरीका बताया गया है:

Kotlin

// 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).bufferedWri>ter().use { writer -
    writer.write(fileContents)
}

Java

// 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.
}

यहां दिया गया कोड स्निपेट, इन्वर्स ऑपरेशन दिखाता है. इसमें इंटरनल स्टोरेज से डेटा पढ़ा जाता है:

Kotlin

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

Java

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.
}

इससे जुड़ी जानकारी:

इस्तेमाल के उदाहरण के आधार पर, बाहरी स्टोरेज में डेटा सेव करना

अपने ऐप्लिकेशन के लिए, बड़ी और संवेदनशील जानकारी न रखने वाली फ़ाइलों के लिए बाहरी स्टोरेज का इस्तेमाल करें. साथ ही, उन फ़ाइलों के लिए भी बाहरी स्टोरेज का इस्तेमाल करें जिन्हें आपका ऐप्लिकेशन अन्य ऐप्लिकेशन के साथ शेयर करता है. आप जिन एपीआई का इस्तेमाल करते हैं वे इस बात पर निर्भर करते हैं कि आपका ऐप्लिकेशन, ऐप्लिकेशन के लिए खास तौर पर बनाई गई फ़ाइलों को ऐक्सेस करने के लिए डिज़ाइन किया गया है या शेयर की गई फ़ाइलों को ऐक्सेस करने के लिए.

अगर किसी फ़ाइल में निजी या संवेदनशील जानकारी नहीं है, लेकिन वह सिर्फ़ आपके ऐप्लिकेशन में उपयोगकर्ता के लिए काम की है, तो फ़ाइल को बाहरी स्टोरेज में ऐप्लिकेशन के लिए खास तौर पर बनाई गई डायरेक्ट्री में सेव करें.

अगर आपके ऐप्लिकेशन को किसी ऐसी फ़ाइल को ऐक्सेस या सेव करना है जो अन्य ऐप्लिकेशन के लिए काम की है, तो अपने इस्तेमाल के उदाहरण के आधार पर, इनमें से किसी एक एपीआई का इस्तेमाल करें:

स्टोरेज वॉल्यूम की उपलब्धता देखना

अगर आपका ऐप्लिकेशन, हटाए जा सकने वाले किसी बाहरी स्टोरेज डिवाइस के साथ इंटरैक्ट करता है, तो ध्यान रखें कि जब आपका ऐप्लिकेशन उस डिवाइस को ऐक्सेस करने की कोशिश कर रहा हो, तब उपयोगकर्ता उसे हटा सकता है. स्टोरेज डिवाइस उपलब्ध है या नहीं, इसकी पुष्टि करने के लिए लॉजिक शामिल करें.

डेटा की वैधता की जांच करना

अगर आपका ऐप्लिकेशन बाहरी स्टोरेज से डेटा का इस्तेमाल करता है, तो पक्का करें कि डेटा का कॉन्टेंट खराब न हुआ हो या उसमें बदलाव न किया गया हो. उन फ़ाइलों को मैनेज करने के लिए लॉजिक शामिल करें जो अब स्टेबल फ़ॉर्मैट में नहीं हैं.

यहां दिए गए कोड स्निपेट में, हैश की पुष्टि करने वाले टूल का उदाहरण शामिल है:

Kotlin

val hash = calculateHash(stream)
// Store "expectedHash" in a secure location.
if< (h>ash == varex<pect>edHash/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(":&quot;) { "%02x".format(it) }
    }
}

Java

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.
    executo&r.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() से मिली इंटरनल कैश डायरेक्ट्री, आपके ऐप्लिकेशन के लिए निजी होती है. हालांकि, बाहरी कैश डायरेक्ट्री निजी नहीं होती.

यहां दिए गए कोड स्निपेट में, हाल ही में डाउनलोड की गई फ़ाइल को कैश मेमोरी में सेव करने का तरीका बताया गया है:

Kotlin

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

Java

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

ध्यान दें: अगर आपने शेयर किए गए स्टोरेज में अपने ऐप्लिकेशन की कैश मेमोरी को सेव करने के लिए, getExternalCacheDir() का इस्तेमाल किया है, तो हो सकता है कि आपका ऐप्लिकेशन चलने के दौरान, उपयोगकर्ता इस स्टोरेज वाले मीडिया को निकाल दे. उपयोगकर्ता के इस व्यवहार की वजह से, कैश मेमोरी में डेटा न मिलने की समस्या को ठीक करने के लिए लॉजिक शामिल करें.

चेतावनी: बाहरी कैश मेमोरी डायरेक्ट्री में मौजूद फ़ाइलों पर कोई सुरक्षा लागू नहीं होती. इसलिए, Android 10 (एपीआई लेवल 29) या इससे पहले के वर्शन को टारगेट करने वाला और WRITE_EXTERNAL_STORAGE की अनुमति वाला कोई भी ऐप्लिकेशन, इस कैश मेमोरी के कॉन्टेंट को ऐक्सेस कर सकता है.

इसी विषय से जुड़ी जानकारी: डेटा और फ़ाइल स्टोरेज के बारे में खास जानकारी

SharedPreferences को प्राइवेट मोड में इस्तेमाल करना

अपने ऐप्लिकेशन के SharedPreferences ऑब्जेक्ट बनाने या उन्हें ऐक्सेस करने के लिए, getSharedPreferences() का इस्तेमाल करते समय MODE_PRIVATE का इस्तेमाल करें. इस तरह, शेयर की गई सेटिंग की फ़ाइल में मौजूद जानकारी को सिर्फ़ आपका ऐप्लिकेशन ऐक्सेस कर सकता है.

अगर आपको अलग-अलग ऐप्लिकेशन के बीच डेटा शेयर करना है, तो SharedPreferences ऑब्जेक्ट का इस्तेमाल न करें. इसके बजाय, ऐप्लिकेशन के बीच सुरक्षित तरीके से डेटा शेयर करने का तरीका अपनाएं.

इससे जुड़ी जानकारी:

सेवाओं और डिपेंडेंसी को अप-टू-डेट रखना

ज़्यादातर ऐप्लिकेशन, खास टास्क पूरे करने के लिए बाहरी लाइब्रेरी और डिवाइस सिस्टम की जानकारी का इस्तेमाल करते हैं. अपने ऐप्लिकेशन की डिपेंडेंसी को अप-टू-डेट रखकर, कम्यूनिकेशन के इन तरीकों को ज़्यादा सुरक्षित बनाया जा सकता है.

Google Play services की सुरक्षा सेवा देने वाली कंपनी के बारे में जानकारी देखना

ध्यान दें: यह सेक्शन सिर्फ़ उन ऐप्लिकेशन पर लागू होता है जो ऐसे डिवाइसों को टारगेट करते हैं जिनमें Google Play services इंस्टॉल है.

अगर आपका ऐप्लिकेशन Google Play services का इस्तेमाल करता है, तो पक्का करें कि यह उस डिवाइस पर अपडेट हो जिस पर आपका ऐप्लिकेशन इंस्टॉल है. यूज़र इंटरफ़ेस (यूआई) थ्रेड से बाहर, एसिंक्रोनस तरीके से जांच करें. अगर डिवाइस अप-टू-डेट नहीं है, तो अनुमति से जुड़ी गड़बड़ी ट्रिगर करें.

जिस डिवाइस पर आपका ऐप्लिकेशन इंस्टॉल है उस पर Google Play services अप-टू-डेट है या नहीं, यह पता करने के लिए, एसएसएल एक्सप्लॉइट से सुरक्षा के लिए, सुरक्षा सेवा देने वाली कंपनी को अपडेट करना गाइड में दिया गया तरीका अपनाएं.

मिलती-जुलती जानकारी:

ऐप्लिकेशन की सभी डिपेंडेंसी अपडेट करना

अपना ऐप्लिकेशन डिप्लॉय करने से पहले, पक्का करें कि सभी लाइब्रेरी, एसडीके, और अन्य डिपेंडेंसी अप-टू-डेट हों:

  • पहले पक्ष की डिपेंडेंसी, जैसे कि Android SDK के लिए, Android Studio में मौजूद अपडेट करने वाले टूल इस्तेमाल करें. जैसे, एसडीके मैनेजर.
  • तीसरे पक्ष की डिपेंडेंसी के लिए, उन लाइब्रेरी की वेबसाइटें देखें जिनका इस्तेमाल आपका ऐप्लिकेशन करता है. साथ ही, उपलब्ध अपडेट और सिक्योरिटी पैच इंस्टॉल करें.

इसी विषय से जुड़ी जानकारी: बिल्ड डिपेंडेंसी जोड़ना

ज़्यादा जानकारी

अपने ऐप्लिकेशन को ज़्यादा सुरक्षित बनाने के तरीके के बारे में ज़्यादा जानने के लिए, यहां दिए गए संसाधन देखें: