एंड्रॉइड में सुरक्षित रूप से टोकन स्टोर करने के तरीके के बारे में अनुवर्ती

इस लेख के प्रस्तावना के रूप में, मैं कुख्यात पाठक के लिए एक छोटा वाक्य बताना चाहता हूं। यह उद्धरण महत्वपूर्ण होगा क्योंकि हम आगे बढ़ते हैं।

पूर्ण सुरक्षा मौजूद नहीं है। सुरक्षा उपायों का एक समूह है, जिसे ढेर किया जा रहा है और संयुक्त किया जा रहा है, जो अपरिहार्य को धीमा करने की कोशिश कर रहा है।

लगभग तीन साल पहले, मैंने अपने एंड्रॉइड एप्लिकेशन को विघटित करने वाले काल्पनिक हमलावर से स्ट्रिंग टोकन को बचाने के लिए कुछ विचार देते हुए एक पोस्ट लिखा था। स्मरण के लिए, और इंटरनेट की अपरिहार्य मृत्यु को दूर करने के लिए, मैं यहां कुछ खंडों को पुन: प्रस्तुत कर रहा हूं।

सबसे आम उपयोग मामलों में से एक तब होता है जब हमारे एप्लिकेशन को डेटा का आदान-प्रदान करने के लिए एक वेब सेवा के साथ संवाद करने की आवश्यकता होती है। यह डेटा एक्सचेंज कम से अधिक संवेदनशील प्रकृति से दोलन कर सकता है, और एक लॉगिन अनुरोध, उपयोगकर्ता डेटा परिवर्तन याचिका, आदि के बीच भिन्न हो सकता है।

लागू किया जाने वाला पूर्ण पहला उपाय क्लाइंट और सर्वर के बीच SSL (सिक्योर सॉकेट लेयर) कनेक्शन का उपयोग कर रहा है। प्रारंभिक बोली पर फिर से जाएं। यह एक पूर्ण गोपनीयता और सुरक्षा सुनिश्चित नहीं करता है, हालांकि यह एक अच्छा प्रारंभिक काम करता है।

जब आप एक SSL कनेक्शन का उपयोग कर रहे होते हैं (जैसे कि जब आप अपने ब्राउज़र में लॉकर देखते हैं) तो यह इंगित करता है कि आपके और सर्वर के बीच कनेक्शन एन्क्रिप्टेड है। सैद्धांतिक स्तर पर, कुछ भी इस अनुरोध के भीतर निहित जानकारी तक नहीं पहुंच सकता है (*)

(*) क्या मैंने उल्लेख किया है कि पूर्ण सुरक्षा मौजूद नहीं है? एसएसएल कनेक्शन अभी भी समझौता किया जा सकता है। यह लेख सभी संभावित हमलों की एक व्यापक सूची प्रदान करने का इरादा नहीं है, लेकिन मैं आपको कुछ संभावनाओं के बारे में बताना चाहता हूं। नकली एसएसएल प्रमाणपत्रों का उपयोग किया जा सकता है, साथ ही साथ मध्य-मध्य हमलों का भी।

आगे बढ़ने दो। हम मान रहे हैं कि हमारा ग्राहक हमारे बैकएंड के साथ एन्क्रिप्टेड एसएसएल चैनल के माध्यम से संचार कर रहा है। वे उपयोगी डेटा का आदान-प्रदान कर रहे हैं, अपने व्यवसाय को खुश कर रहे हैं। लेकिन हम एक अतिरिक्त सुरक्षा परत प्रदान करना चाहते हैं।

आजकल इस्तेमाल किया जाने वाला एक अगला तार्किक कदम संचार में उपयोग किए जाने वाले प्रमाणीकरण टोकन या एपीआई कुंजी प्रदान करना है। यह इस तरह से काम करता है। हमारे बैकएंड को एक याचिका मिलती है। हमें कैसे पता चलेगा कि याचिका हमारे सत्यापित ग्राहकों में से एक है, न कि एक यादृच्छिक दोस्त जो हमारे एपीआई तक पहुंच प्राप्त करने की कोशिश कर रहा है? बैकएंड जाँच करेगा कि क्या क्लाइंट एक वैध एपीआई कुंजी प्रदान कर रहा है। यदि पिछला कथन सत्य होता है, तो हम अनुरोध के साथ आगे बढ़ते हैं। अन्यथा, हम इसे अस्वीकार करते हैं और हमारे व्यवसाय की प्रकृति के आधार पर हम कुछ सुधारात्मक उपाय करते हैं (जब यह हो रहा है, मैं विशेष रूप से क्लाइंट से आईपी और आईडी स्टोर करना पसंद करता हूं, यह देखने के लिए कि यह कितनी बार होता है। जब आवृत्ति सूजन से अधिक होती है। यह मेरे ठीक स्वाद के लिए वांछनीय है, मैं एक प्रतिबंध पर विचार कर रहा हूं या निकटता से देख रहा हूं कि इनोलाइट इंटरनेट दोस्त क्या हासिल करने की कोशिश कर रहा है)।

जमीन से हमारे महल का निर्माण करें। हमारे एप्लिकेशन में, हम संभवतः API_KEY नामक एक चर जोड़ेंगे जो प्रत्येक अनुरोध में स्वचालित रूप से इंजेक्ट हो जाता है (यदि आप एंड्रॉइड का उपयोग कर रहे हैं, तो शायद आपके रेट्रोफिट क्लाइंट में)।

निजी अंतिम स्थिर स्ट्रिंग API_KEY = "67a5af7f89ah3katf7m20fdj202"

यह बहुत अच्छा है, और अगर हम अपने ग्राहक को प्रमाणित करना चाहते हैं तो यह काम करता है। समस्या यह है कि अपने आप में एक बहुत प्रभावी परत प्रदान नहीं करता है।

यदि आप एप्लिकेशन को अपघटित करने और स्ट्रिंग्स की तलाश में खोज करने के लिए apktool का उपयोग करते हैं, तो आप परिणामी .smali फ़ाइलों में से एक में पाएंगे।

const-string v1, "67a5af7f89ah3katf7m20fdj202"

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

क्या प्रहरी हमें इस स्ट्रिंग को सुरक्षित करने में मदद कर सकता है, इसलिए हमें इसके बारे में चिंता करने की ज़रूरत नहीं है? ज़रुरी नहीं। अपने FAQ में रक्षक ने कहा कि स्ट्रिंग एन्क्रिप्शन पूरी तरह से संभव नहीं है।

एंड्रॉइड द्वारा प्रदान किए गए अन्य तंत्रों में से एक में इस स्ट्रिंग को बचाने के बारे में क्या है, जैसे कि SharedPreferences? यह बमुश्किल एक अच्छा विचार है। SharedPreferences एमुलेटर या किसी भी रूट किए गए डिवाइस से आसानी से पहुँचा जा सकता है। कुछ साल पहले श्रीनिवास नाम के एक शख्स ने इस बात का सबूत दिया कि कैसे वीडियो-गेम में स्कोर को बदला जा सकता है। हम यहाँ विकल्पों से बाहर चल रहे हैं!

मूल विकास किट (NDK)

मैं यहां प्रस्तावित प्रारंभिक मॉडल को ताज़ा करने जा रहा हूं, और हम इसके माध्यम से और अधिक सुरक्षित विकल्प प्रदान करने के लिए इसके माध्यम से कैसे पुनरावृति कर सकते हैं। आइए छवि को दो कार्य करें जो हमारे डेटा को एन्क्रिप्ट और डिक्रिप्ट करने का काम कर सकते हैं:

यहां कुछ भी नहीं फैंसी। ये दो कार्य एक महत्वपूर्ण मूल्य और एक स्ट्रिंग को एन्कोडेड या डिकोड किया जाएगा। वे क्रमशः एन्क्रिप्टेड या डिक्रिप्ट किए गए टोकन को वापस कर देंगे। हम निम्न फ़ंक्शन को निम्नानुसार कहेंगे:

क्या आप दिशा का अनुमान लगा रहे हैं? यह सही है। हम मांग पर अपना टोकन एन्क्रिप्ट और डिक्रिप्ट कर सकते हैं। यह सुरक्षा की एक अतिरिक्त परत प्रदान करता है: जब कोड बाधित हो जाता है, तो यह स्ट्रिंग्स की खोज करने और उस स्ट्रिंग के आसपास के वातावरण की जांच करने के रूप में सीधा नहीं है। लेकिन क्या आप अभी भी एक समस्या का पता लगा सकते हैं जिसे हल करने की आवश्यकता है?

क्या आप?

अगर आपने अभी तक इसका पता नहीं लगाया है तो इसे कुछ सेकंड और दें।

हाँ आप सही है। हमारे पास एक एन्क्रिप्शन कुंजी है जिसे स्ट्रिंग के रूप में भी संग्रहीत किया जा रहा है। यह अस्पष्टता से सुरक्षा की अधिक परतों को जोड़ रहा है, लेकिन हमारे पास अभी भी सादे पाठ पर एक टोकन है, भले ही यह टोकन एन्क्रिप्शन के लिए उपयोग किया जाता है या टोकन-प्रति है।

चलिए अब NDK का उपयोग करने जा रहे हैं, और हमारे सुरक्षा तंत्र को बनाए रखते हैं।

NDK हमें अपने Android कोड से C ++ कोड आधार तक पहुंचने देता है। पहले दृष्टिकोण के रूप में, यह सोचने के लिए एक मिनट दें कि क्या करना है। हमारे पास एक मूल सी ++ फ़ंक्शन हो सकता है जो एपीआई कुंजी या जो भी संवेदनशील डेटा हम स्टोर करने की कोशिश कर रहे हैं, उसे स्टोर करता है। यह फ़ंक्शन बाद में कोड से बुलाया जा सकता है, और किसी भी जावा फ़ाइल में कोई स्ट्रिंग संग्रहीत नहीं किया जाएगा। यह विघटनकारी तकनीकों के खिलाफ एक स्वचालित सुरक्षा प्रदान करेगा।

हमारी C ++ फ़ंक्शन निम्नानुसार दिखाई देगी:

यह आसानी से आपके जावा कोड में कहा जाएगा:

और एन्क्रिप्शन / डिक्रिप्शन फ़ंक्शन को अगले स्निपेट में कहा जाएगा:

अगर हम जानते हैं कि कोई एपीके उत्पन्न करता है, तो उसे बाधित करें, इसे अपघटित करें और मूल फ़ंक्शन getSecretKey () में निहित स्ट्रिंग को एक्सेस करने का प्रयास करें, हम इसे ढूंढ नहीं पाएंगे! विजय?

ज़रुरी नहीं। NDK कोड वास्तव में असंतुष्ट और निरीक्षण किया जा सकता है। यह कठिन हो रहा है, और आपको अधिक उन्नत टूल और तकनीकों की आवश्यकता शुरू हो रही है। आपको 95% स्क्रिप्ट बच्चों से छुटकारा मिल गया, लेकिन पर्याप्त संसाधनों और प्रेरणा के साथ एक टीम अभी भी टोकन तक पहुंचने में सक्षम होगी। इस वाक्य को याद रखें?

पूर्ण सुरक्षा मौजूद नहीं है। सुरक्षा उपायों का एक समूह है, जिसे ढेर किया जा रहा है और संयुक्त किया जा रहा है, जो अपरिहार्य को धीमा करने की कोशिश कर रहा है।
आप अभी भी असंतुष्ट कोड स्ट्रिंग स्ट्रिंग में पहुंच सकते हैं!

उदाहरण के लिए, हेक्स रेज, देशी फाइलों को डिकम्पोज करने में बहुत अच्छा काम करता है। मुझे यकीन है कि उपकरणों का एक समूह है, जो एंड्रॉइड के साथ उत्पन्न किसी भी मूल कोड को डिक्रिप्ट कर सकता है (मैं हेक्स किरणों से जुड़ा नहीं हूं और न ही उनसे किसी भी तरह का मौद्रिक मुआवजा प्राप्त कर सकता हूं)।

तो हम बिना बैकएंड और क्लाइंट के बीच बातचीत करने के लिए किस समाधान का उपयोग कर सकते हैं?

डिवाइस पर वास्तविक समय में कुंजी उत्पन्न करें।

आपके डिवाइस को किसी भी प्रकार की कुंजी को स्टोर करने की आवश्यकता नहीं है और एक स्ट्रिंग शाब्दिक सुरक्षा के सभी झंझटों से निपटने की आवश्यकता है! यह एक बहुत पुरानी तकनीक है जिसका उपयोग दूरस्थ कुंजी सत्यापन जैसी सेवाओं द्वारा किया जाता है।

  1. क्लाइंट एक फ़ंक्शन () जानता है जो एक कुंजी देता है।
  2. बैकएंड क्लाइंट में कार्यान्वित फ़ंक्शन () को जानता है
  3. क्लाइंट फ़ंक्शन () के माध्यम से एक कुंजी बनाता है, और यह सर्वर को दिया जाता है।
  4. सर्वर इसे सत्यापित करता है, और अनुरोध के साथ आगे बढ़ता है।

क्या आप डॉट्स कनेक्ट कर रहे हैं? एक मूल फ़ंक्शन होने के बजाय जो आपको एक स्ट्रिंग देता है (आसानी से पहचाने जाने योग्य) क्यों ऐसा फ़ंक्शन नहीं है जो आपको 1 और 100 के बीच तीन यादृच्छिक अभाज्य संख्याओं का योग देता है? या एक फ़ंक्शन जो वर्तमान दिन को यूनिक्स में व्यक्त किया गया है और प्रत्येक अलग अंक में 1 जोड़ता है? डिवाइस से कुछ प्रासंगिक जानकारी लेने के बारे में क्या है, जैसे कि उपयोग की जाने वाली स्मृति की मात्रा, एन्ट्रापी की उच्च डिग्री प्रदान करने के लिए?

अंतिम पैराग्राफ में विचारों की एक श्रृंखला शामिल है, लेकिन हमारे काल्पनिक पाठक ने मुख्य बिंदु को उम्मीद से लिया है।

सारांश

  1. पूर्ण सुरक्षा मौजूद नहीं है।
  2. सुरक्षा के एक उच्च स्तर को प्राप्त करने के लिए सुरक्षा के उपायों के साथ संयोजन करना महत्वपूर्ण है।
  3. अपने कोड में स्ट्रिंग शाब्दिकों को संग्रहीत न करें।
  4. स्व-जनित कुंजी बनाने के लिए NDK का उपयोग करें।

पहला वाक्य याद है?

पूर्ण सुरक्षा मौजूद नहीं है। सुरक्षा उपायों का एक समूह है, जिसे ढेर किया जा रहा है और संयुक्त किया जा रहा है, जो अपरिहार्य को धीमा करने की कोशिश कर रहा है।

मैं एक बार फिर बताना चाहता हूं कि आपका लक्ष्य आपके कोड को यथासंभव सुरक्षित रखना है, बिना इस परिप्रेक्ष्य को खोए कि 100% सुरक्षा अप्राप्य है। लेकिन अगर आप अपने कोड को इस तरह से सुरक्षित रखने में सक्षम हैं जिसके लिए आपके पास किसी भी समझदार जानकारी को डिक्रिप्ट करने के लिए भारी मात्रा में संसाधनों की आवश्यकता होती है, तो आप अच्छी तरह से और शांत होकर सो पाएंगे।

एक छोटा सा अस्वीकरण

मुझे पता है। आपको यहाँ तक मिल गया, पूरे लेख में यह सोचकर कि "यह आदमी डेक्सगार्ड का उल्लेख कैसे नहीं कर रहा है, और सभी परेशानी से गुजर रहा है"। तुम सही हो। डेक्सगार्ड वास्तव में स्ट्रिंग्स को बाधित कर सकते हैं, और वे इस पर बहुत अच्छा काम करते हैं। हालाँकि, डेक्सगार्ड मूल्य निर्धारण निषेधात्मक हो सकता है। मैंने महत्वपूर्ण सुरक्षा प्रणालियों के साथ पिछली कंपनियों में डेक्सगार्ड का उपयोग किया है, लेकिन यह हर किसी के लिए एक विकल्प नहीं हो सकता है। और, सॉफ़्टवेयर डेवलपमेंट के साथ-साथ जीवन में, आपके पास जितने अधिक विकल्प हैं, उतना ही समृद्ध और अधिक प्रचुर मात्रा में दुनिया को प्राप्त होता है।

हैप्पी कोडिंग!

मैं अपने ट्विटर अकाउंट में सामान्य रूप से सॉफ्टवेयर इंजीनियरिंग और जीवन के बारे में अपने विचार लिखता हूं। यदि आपको यह लेख पसंद आया है या इसने आपकी मदद की है, तो इसे साझा करने के लिए स्वतंत्र महसूस करें, ♥ इसे और / या एक टिप्पणी छोड़ दें। यह वह मुद्रा है जो शौकिया लेखकों को ईंधन देती है।