2012-07-26 8 views
40

असल में यह सार्वजनिक कुंजी (क्या सार्वजनिक कुंजी की परिभाषा तो है?) की रक्षा करने के बारे में थोड़ा मूर्खतापूर्ण लेकिन अनुसार documentation by Google है:Google Play सार्वजनिक कुंजी जब InApp बिलिंग कर की रक्षा के लिए कैसे

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

क्या ऐसा करने के लिए कोई अनुशंसित तरीका है?

मुझे पता है कि यह करने के लिए कई तरीके हैं, मैं सिर्फ नहीं उसी तरह पालन करने के लिए कैसे लोगों को पासवर्ड अतीत में hashing (जैसे md5, SHA1 आदि) को संभालने चाहता हूँ, मैं सबसे अच्छा अभ्यास जानना चाहता हूँ उपर्युक्त उपयोग मामले में।

उत्तर

35

यह यहां बहुत कुछ आता है :) आपके द्वारा उद्धृत अनुच्छेद के पीछे विचार यह है कि इन-ऐप बिलिंग सुरक्षित होने के लिए, आपको लेनदेन हस्ताक्षर सत्यापित करने की आवश्यकता है। वे आपके डेवलपर खाते से जुड़े एक निजी कुंजी के साथ हस्ताक्षरित हैं। कुंजी Google के सर्वर पर रहती है, इसलिए यह मानना ​​सुरक्षित है कि कोई भी इसके साथ डेटा पर हस्ताक्षर नहीं कर सकता है। इसे सत्यापित करने के लिए आपको अपनी सार्वजनिक कुंजी की आवश्यकता है, जिसे आप डेवलपर कंसोल से कॉपी कर सकते हैं। अगर किसी ने इसे आपके ऐप में बदल दिया है, तो वे इसे अनधिकृत स्रोतों से इन-ऐप बिलिंग लेन-देन स्वीकार करने के लिए मूर्ख बना सकते हैं, क्योंकि यदि वे सार्वजनिक कुंजी लगाते हैं, तो वे शायद इसी निजी कुंजी को भी नियंत्रित कर सकते हैं। अभ्यास में हालांकि, isLicensed(), hasItem() या आपके जैसी समान विधियों के लिए हमेशा सही होने के लिए सही जगहों पर अपने कोड को संशोधित करना कहीं अधिक आसान है और कोई भी ऐसा नहीं करता है।

कुंजी की रक्षा करने का सबसे अच्छा तरीका है, निश्चित रूप से, आपके ऐप में कुंजी नहीं है। अपने सर्वर पर सभी लेनदेन सत्यापन तर्क को ले जाएं, और उससे कनेक्ट करने के लिए HTTPS का उपयोग करें। यह सुनिश्चित करने के लिए कि आप अपने सर्वर से बात कर रहे हैं, प्रमाण पत्र श्रृंखला को उचित रूप से मान्य करें। अन्यथा, कोई DNS के साथ गड़बड़ कर सकता है और अपने ऐप को अपने सर्वर से कनेक्ट करने के लिए मूर्ख बना सकता है। आईओएस खरीद के खिलाफ एक समान हमले की घोषणा कुछ हफ्ते पहले की गई थी।

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

+1

आपका क्या मतलब है "अभ्यास में हालांकि, सही जगहों पर अपने कोड को आसानी से संशोधित करना कहीं आसान है, हमेशा के लिए सत्य लौटाएं(), हैइटम() या आपके पास समान तरीके हो सकते हैं और कोई भी ऐसा नहीं करता है। " वह वाक्य पूरी तरह से समझ में नहीं आता है। कृपया स्पष्ट करें। – Stunner

+10

इसका मतलब है कि ऐप को पैच करना और किसी भी लाइसेंसिंग चेक को सीधे अक्षम करना आसान है, फिर कुंजी और मैस को प्रतिस्थापित करने का प्रयास करें हस्ताक्षर सत्यापन को बेवकूफ बनाने का प्रयास करें। –

+0

~ "** शायद संबंधित निजी कुंजी ** को भी नियंत्रित करें"। लेकिन इन-ऐप बिलिंग अनुरोध डिवाइस पर Play Store एपीके के माध्यम से जाते हैं। तो कोई उस तर्क को कैसे नियंत्रित या कुशलतापूर्वक इस्तेमाल करेगा ?? –

4

सर्वर की तरफ अपनी सार्वजनिक कुंजी स्टोर करें और एक बार जब आप Google Play से प्रतिक्रिया प्राप्त कर लें तो कुंजी को सत्यापित करने के लिए सर्वर पर प्रतिक्रिया भेजें और सर्वर पर अपना ऑपरेशन करें।

+1

ऐसा लगता है कि इस तरह के सर्वर-साइड इंफ्रास्ट्रक्चर की स्थापना की गई है। –

32

कम से कम सरल पाठ परिवर्तन करें। विचार यह है कि सादे डेक्स डिससेबलिंग आपकी सार्वजनिक कुंजी को प्रकट नहीं करेगी।

/** 
* Simple String transformation by XOR-ing all characters by value. 
*/ 
static String stringTransform(String s, int i) { 
    char[] chars = s.toCharArray(); 
    for(int j = 0; j<chars.length; j++) 
     chars[j] = (char)(chars[j]^i); 
    return String.valueOf(chars); 
} 

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

यहाँ समारोह है कि बनाता है सरल स्ट्रिंग एन्कोडिंग/डिकोडिंग के उदाहरण है। यह Google द्वारा सुझाए गए "एक्सओआर" विधि की तरह है।

आप 'i' पैरामीटर स्वयं बनाते हैं, 0x27 या अन्य कोई भी यादृच्छिक काम करेगा। यदि आप इस तरह से अधिक तार छिपाते हैं, तो प्रत्येक ट्रांसफॉर्म के लिए अलग-अलग 'i' का उपयोग करें।

+14

रहस्य :) यदि आप प्रोग्रामर हैं, तो आप निश्चित रूप से ऐसी समस्या से उबरते हैं। –

+2

@NPike, आपको जावा में इसका उपयोग करने के लिए स्ट्रिंग से बचने की आवश्यकता होगी। इस वेबसाइट को आज़माएं: http://www.htmlescape.net/javaescape_tool.html दुर्भाग्यवश, मैंने पाया कि ट्रांसफॉर्म प्रक्रिया अक्सर एक स्ट्रिंग में परिणामस्वरूप होती है जो ग्रहण का सामना नहीं कर सका (यहां तक ​​कि जब भी बच निकला), तो आपको ट्विक करना होगा जब तक आप कुछ प्राप्त नहीं कर लेते हैं तब तक एक्सओआरएड किया जा रहा है ... –

11

मैन्युअल रूप से कुंजी को obfuscating करने के विकल्प के रूप में, आप एक obfuscator स्वचालित रूप से यह भी कर सकते हैं। ProGuard एंड्रॉइड एसडीके का हिस्सा है, लेकिन यह ज्यादातर वर्ग/फ़ील्ड/विधि नामों को खराब करता है, स्ट्रिंग नहीं। एंड्रॉइड के लिए इसका विशेष भाई, DexGuard, स्ट्रिंग एन्क्रिप्शन, कक्षा एन्क्रिप्शन और प्रतिबिंब लागू करने, obfuscation की अधिक परतों को जोड़ सकते हैं। यह मुफ़्त नहीं है, लेकिन यह समय बचाता है और यह मैन्युअल रूप से करने से शायद अधिक प्रभावी है।

(मैं ProGuard और DexGuard डेवलपर हूं)

+0

कमाल !! धन्यवाद .. एक्सओआर विधि सुरक्षित है ?? –

+1

सिर्फ एक साधारण स्ट्रिंग को खराब करने के लिए डेक्सगार्ड ओवरकिल नहीं है? मेरा मतलब है, गारंटी क्या है कि यह वैसे भी ठीक करेगी? –

1

सार्वजनिक कुंजी बेस 64 एन्कोडेड ([a-zA-Z0-9+/]) है ताकि आप आसानी से बिल्कुल समझ से परे स्ट्रिंग से बचने के लिए आवश्यकता से बचने कर सकते हैं @ PointerNull के दशक में एक कष्टप्रद समस्या यह है के रूप में उपाय।

इसके बजाए, आप पहले वर्ण में चरित्र को 6-बिट int में परिवर्तित करके obfuscation निष्पादित कर सकते हैं। फिर बिट मैनिपुलेशन (उदा। एक्सओआर-आईएनजी) करें और फिर बेस 64-एनकोडेड चार में कनवर्ट करें। किसी भी चरित्र से बचने की गारंटी की गारंटी नहीं है।

संबंधित मुद्दे