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 डिकंपाइल करते हैं:
unzip myapp.apk
या APK और Unzip here
पर राइट क्लिक करें। classes.dex
फ़ाइल प्रकट होती है।
- dex2jar के साथ JAR फ़ाइल में कनवर्ट करें।
dex2jar.sh classes.dex
निष्पादित करने के बाद, classes_dex2jar.jar
फ़ाइल प्रकट होता है।
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 कोड पढ़ने में कठिनाई बढ़ जाती है। हमें कोड को इस तरह से खराब नहीं करना चाहिए, क्योंकि:
- यह सुरक्षा का भ्रम देता है।
- यह डेवलपर के समय का अपशिष्ट है।
- यह कोड की पठनीयता कम करता है।
आधिकारिक 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()
था, हम हमेशा डिस्प्लेल्ड कोड चला सकते हैं और देख सकते हैं कि यह क्या उत्पादन कर रहा है। या इसे चरण-दर-चरण डीबग करें।
ध्यान दें कि इस पर हमला करने वाला कोई व्यक्ति इनपुट पासवर्ड अनुमान पर किए गए कार्यों का पालन करेगा। ऐतिहासिक रूप से तुलनात्मक रूप से वास्तविक पासवर्ड संग्रहीत करने की प्राथमिकता नहीं है, बल्कि कम्प्यूटेशनल रूप से महंगा हैश फ़ंक्शंस का परिणाम, इस विचार के साथ कि यदि आप हैश ("उत्तर") को जानते हैं, तो यह मिलान करने वाला पासवर्ड पूरी तरह से महंगा था ("प्रश्न")। लेकिन क्लाउड कंप्यूटिंग और बुरी जुड़वां बोनेट की उम्र में, मध्यम लंबाई का पासवर्ड काफी क्रैक करने योग्य हो सकता है। –
मेरा अद्यतन प्रश्न देखें। मेरा मतलब है कि ऐसे मामले जहां पासवर्ड को ऐप द्वारा ही प्रदान किया जाना है, न कि उपयोगकर्ता द्वारा। मैं उस पर थोड़ा अस्पष्ट था, इसके बारे में खेद है। – BadCash