2014-04-08 7 views
8

कभी-कभी आपको ऐप में एक पासवर्ड स्टोर करने की आवश्यकता होती है, जैसे उपयोगकर्ता नाम/पासवर्ड अपने सर्वर से संचार करने के लिए। इन मामलों में पासवर्ड संग्रहीत करने की सामान्य प्रक्रिया का पालन करना संभव नहीं है - यानी पासवर्ड हैश, हैश स्टोर करें, हैश किए गए उपयोगकर्ता इनपुट की तुलना करें - क्योंकि आपके पास हैश की तुलना करने के लिए कोई उपयोगकर्ता इनपुट नहीं है। पासवर्ड को ऐप द्वारा ही प्रदान किया जाना चाहिए। तो एपीके में संग्रहीत पासवर्ड की रक्षा कैसे करें? क्या नीचे से एक पासवर्ड-जनरेटिंग फ़ंक्शन उचित रूप से सुरक्षित होगा?एपीके में स्ट्रिंग के सरल छिपाने/obfuscation?

सादा पाठ:

String password = "$()&HDI?=!"; 

सरल कहानियो:

private String getPassword(){ 
    String pool = "%&/@$()7?=!656sd8KJ%&HDI!!!G98y/&%=?=*^%&ft4%("; 
    return pool.substring(4, 7) + pool.substring(20, 24) + pool.substring(8, 11); 
} 

मैं जानता हूँ कि ProGuard कुछ कहानियो की क्षमता है, लेकिन मैं क्या ऊपर "कहानियो" तकनीक जब यह संकलित है करता है के बारे में उत्सुक हूँ, और किसी के लिए एपीके और/या अन्य परिष्कृत तकनीकों का उपयोग करके इसे समझना कितना मुश्किल होगा?

+0

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

+0

मेरा अद्यतन प्रश्न देखें। मेरा मतलब है कि ऐसे मामले जहां पासवर्ड को ऐप द्वारा ही प्रदान किया जाना है, न कि उपयोगकर्ता द्वारा। मैं उस पर थोड़ा अस्पष्ट था, इसके बारे में खेद है। – BadCash

उत्तर

13

tl; डॉ क्या आप जानते APK डिकंपाइल करने के लिए कैसे, तो आप आसानी पासवर्ड, चाहे कितना समझ से परे कोड था मिल सकता है। एपीके में पासवर्ड स्टोर न करें, यह सुरक्षित नहीं है।

मैं ProGuard पता कुछ कहानियो की क्षमता है, लेकिन मैं उत्सुक क्या ऊपर "कहानियो" तकनीक जब यह संकलित है करता है, और कितना मुश्किल है किसी में देख कर यह पता लगाने की के लिए यह होगा के बारे में हूँ एपीके और/या अन्य परिष्कृत तकनीकों का उपयोग कर रहे हैं?

मैं आपको दिखाऊंगा कि यह कितना आसान है। यहाँ एक Android SSCCE जो हम डिकंपाइल जाएगा:

MyActivity.java:

public class MyActivity extends Activity { 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.main); 

     TextView text = (TextView) findViewById(R.id.text); 
     text.setText(getPassword()); 
    } 

    private String getPassword() { 
     String pool = "%&/@$()7?=!656sd8KJ%&HDI!!!G98y/&%=?=*^%&ft4%("; 
     return pool.substring(4, 7) + pool.substring(20, 24) + pool.substring(8, 11); 
    } 
} 

main.xml:

<?xml version="1.0" encoding="utf-8"?> 
<TextView xmlns:android="http://schemas.android.com/apk/res/android" 
      android:id="@+id/text" 
      android:layout_width="fill_parent" 
      android:layout_height="wrap_content"/> 

यह संकलन और चल रहा है कि हम एक TextView पर $()&HDI?=! देख सकते हैं के बाद।

के एक APK डिकंपाइल करते हैं:

  1. unzip myapp.apk या APK और Unzip here पर राइट क्लिक करें। classes.dex फ़ाइल प्रकट होती है।
  2. dex2jar के साथ JAR फ़ाइल में कनवर्ट करें। dex2jar.sh classes.dex निष्पादित करने के बाद, classes_dex2jar.jar फ़ाइल प्रकट होता है।
  3. classes_dex2jar.jar पर कुछ जावा Decompiler, उदाहरण के JD-GUI के लिए उपयोग करना, हम MyActivity.class से इस तरह के जावा कोड को पुनः प्राप्त:

    public class MyActivity extends Activity 
    { 
        private String getPassword() 
        { 
         return "%&/@$()7?=!656sd8KJ%&HDI!!!G98y/&%=?=*^%&ft4%(".substring(4, 7) 
    + "%&/@$()7?=!656sd8KJ%&HDI!!!G98y/&%=?=*^%&ft4%(".substring(20, 24) 
    + "%&/@$()7?=!656sd8KJ%&HDI!!!G98y/&%=?=*^%&ft4%(".substring(8, 11); 
        } 
    
        public void onCreate(Bundle paramBundle) 
        { 
         super.onCreate(paramBundle); 
         setContentView(2130903040); 
         ((TextView)findViewById(2131034112)).setText(getPassword()); 
        } 
    } 
    

ProGuard ज्यादा मदद नहीं कर सकता, कोड अभी भी आसानी से पढ़ा जा सके।

नीचे एक तरह एक पासवर्ड पैदा समारोह यथोचित सुरक्षित होगा:

ऊपर के आधार पर, मैं पहले से ही आप इस प्रश्न के लिए एक जवाब दे सकते हैं?

नहीं। जैसा कि आप देख सकते हैं, यह एक छोटे से बिट द्वारा deobfuscated कोड पढ़ने में कठिनाई बढ़ जाती है। हमें कोड को इस तरह से खराब नहीं करना चाहिए, क्योंकि:

  1. यह सुरक्षा का भ्रम देता है।
  2. यह डेवलपर के समय का अपशिष्ट है।
  3. यह कोड की पठनीयता कम करता है।

आधिकारिक Android दस्तावेज़ में, Security and Design भाग में, वे इस की रक्षा के लिए अपने Google Play सार्वजनिक कुंजी की सलाह दे रहे हैं:

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

ठीक है, तो चलो कि कोशिश करते हैं:

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.main); 

    TextView text = (TextView) findViewById(R.id.text); 
    text.setText(xor("[email protected]&IHY", "ehge13ovux")); 
} 

private String xor(String a, String b) { 
    StringBuilder sb = new StringBuilder(); 
    for (int i = 0; i < a.length() && i < b.length(); i++) { 
     sb.append((char) (a.charAt(i)^b.charAt(i))); 
    } 
    return sb.toString(); 
} 

, एक TextView पर $()&HDI?=! देता है अच्छा।

decompiled संस्करण:

public void onCreate(Bundle paramBundle) 
{ 
    super.onCreate(paramBundle); 
    setContentView(2130903040); 
    ((TextView)findViewById(2131034112)).setText(xor("[email protected]&IHY", "ehge13ovux")); 
} 

private String xor(String paramString1, String paramString2) 
{ 
    StringBuilder localStringBuilder = new StringBuilder(); 
    for (int i = 0; (i < paramString1.length()) && (i < paramString2.length()); i++) { 
     localStringBuilder.append((char)(paramString1.charAt(i)^paramString2.charAt(i))); 
    } 
    return localStringBuilder.toString(); 
} 

पहले की तरह बहुत इसी तरह की स्थिति।

भले ही हमारे पास बेहद जटिल कार्य soStrongObfuscationOneGetsBlind() था, हम हमेशा डिस्प्लेल्ड कोड चला सकते हैं और देख सकते हैं कि यह क्या उत्पादन कर रहा है। या इसे चरण-दर-चरण डीबग करें।

+4

मुझे आपका जवाब पसंद आया, लेकिन मुझे सलाह नहीं है कि क्या करना है। "एपीके में पासवर्ड स्टोर न करें" बहुत मदद नहीं करता है क्योंकि एपीआई कुंजी कहीं कहीं भी जरूरी है। – arenaq

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