2010-12-13 209 views
55

我只是使用proguard對我的Android代碼進行了模糊處理,然後對其進行了反編譯。有很多字符串我真的想躲在窺探之下。當我反編譯我的代碼時,字符串在那裏給大家看...並改變。其中一個字符串是我的許可服務器的URL,他們實際上可以將url更改爲指向假服務器(因爲我將向公衆發佈服務器代碼)。隱藏這類信息的最佳方式是什麼?在混淆代碼中隱藏字符串

此外,我注意到R類字符串都是隨機數字,但我無法在反編譯的代碼中找到R類。它在哪裏?

敵人例如我看到:new SimpleCursorAdapter(localActivity, 2130903058, localCursor, arrayOfString, arrayOfInt);

2130903058是一個佈局文件,但它是什麼引用?這個數字除非指向某種地址,否則沒有任何意義。

回答

31

假設你對隱晦而不是安全感到高興,那麼可以使用許多機制,但像proguard這樣的混淆器不能幫助你。

要實現這一點,您需要自己對字符串進行編碼或加密,您使用的方法取決於您要防範的方法,如果您只是試圖隱藏明顯的檢查,那麼編碼可能是足夠的(請參閱android.util.Base64,​​)。請注意,編碼處於「無法安全」狀態,並且它將刪除對您網站的明顯引用。

如果您試圖防禦更多的東西,那麼您可以移動到實際加密字符串,要做到這一點,你會使用對稱密碼,如AES通過javax.crypto.Cipher,http://www.androidsnippets.org/snippets/39/index.html提供了一個體面的使用示例。再次,這是更惱人的,然後安全的將是黑客,因爲您將需要將密鑰存儲在您的jar中的某個地方,從而否定任何加密安全。

爲了使這更清楚,基本步驟是:

  1. 手動創建一個使用已知的密鑰來加密您的字符串。
  2. 轉換代碼中使用此字符串的解密版本,例如:

前:

public class Foo { 
    private String mySecret = "http://example.com"; 

    ... 
} 

變爲:

public class Foo { 
    private String encrypted = "<manually created encrypted string>"; 
    private String key = "<key used for encryption"; 
    private String mySecret = MyDecryptUtil.decrypt(encrypted, key); 

    ... 
} 

A(良好)替代了這一切正在考慮使用第三方DRM解決方案,如谷歌提供的許可服務器http://android-developers.blogspot.com/2010/07/licensing-service-for-android.html。這可能比你推出自己的東西更安全,但受到與我上面描述的非常類似的限制。

+0

什麼存儲服務器上的一些類文件。應用程序已安裝後是否可以下載並安裝新的類文件?有沒有辦法以安全的方式做到這一點,即不允許某人複製已經註冊的設備的文件,並只使用它們? – jax 2010-12-13 09:38:02

+18

您可以添加多個圖層,但最終您無法防止已確定的黑客。在某些時候,你最好將自己的時間投入到其他產品中,做得足夠好(足夠有價值),而且人們不會想要偷走它。 – 2010-12-13 09:43:32

+3

「最後,你不能防止一個確定的黑客」 - >這是這個長長的主題中最好的單詞。馬克是這樣說的,我們能做的最好的只是減緩攻擊者。 – Krypton 2013-04-04 01:43:31

0

你應該谷歌的「只是另一個Perl黑客」。這些程序是用混淆的代碼打印出一個字符串。網上還有很多其他語言的例子,然後是Perl。

Wikipedia entry

+0

是的,但如果黑客知道您使用了JAPH,那麼他/她可以輕鬆解密您的API密鑰? – 2017-02-05 00:19:17

6

我所做的就是在我的全球公用事業類中創建靜態字符串的一個長長的清單。在很長的字符串列表中的某個位置,我把我的密鑰放在多個塊中。

用我的代碼很容易看出真正的密鑰是什麼 - 但是一旦混淆器開始工作,所有的靜態都會有A,B,C等名稱,並且不會再容易發現。

+0

可否請您提供您所說的示例代碼。謝謝 – Sam 2014-03-06 06:09:54

+2

嗨山姆,只是用一大堆'public static String variable1 =「假數據」創建一個公共類;'當我說「整個一堆」時,我的意思是像那些字符串的數百個。使用excel創建一個像這樣的文件很容易。然後,在所有這些「假」行中隱藏一些重要的數據。一旦混淆器開始工作,所有這些數據將看起來像一團糟。當你想使用這些數據時,結合幾個單獨的字符串來重新創建你想要隱藏的內容。您可以通過編碼這些文本行來進一步進一步,使其看起來更像一團糟。 – 2014-03-06 20:00:19

+0

重點在於:要讓逆向工程代碼的人必須爲其工作。你可以做得越無吸引力,它不值得他們的時間的可能性越好。 – 2014-03-06 20:05:02

2

我使用了ROT47。這不是很安全,但易於使用和實施,因爲它是一個對稱編碼器/解碼器

0

您可以使用DexGuard加密字符串,可能比手動實現更有效,並且不會增加源代碼的負擔。

+6

,但DexGuard不是免費的 – 2016-07-16 18:54:42

+0

我認爲是免費的,你可以通過電子郵件得到DexGuard – 2016-07-24 04:31:10

+0

你能再次檢查,因爲根據我的知識它不是免費的? – 2017-02-05 00:14:37

19

大家好。

  1. secret是要隱藏

  2. 找到你的調試/ release.keystore的keyhash文本。讓​​成爲這個關鍵。

(使用工具keytool中+ OpenSSL的:keytool -exportcert -alias androiddebugkey -keystore ~/.android/debug.keystore | openssl sha1 -binary | openssl base64

  • 使用的工具(外部機器人代碼)與​​

    encrypted = encode (secret, k1)加密secret

  • (例如:https://jwt.io,對於java:https://github.com/jwtk/jjwt)。

    1. 在你的android java代碼中寫下encrypted。當你需要的encrypted解碼版本(這是,原來secret)寫

    original = decode(encrypted, get_my_keyhash_programmatically())

    這就是全部。這是可行的,因爲原始的secret沒有顯示在java源代碼上,也沒有對​​進行解碼。而且,如果黑客想要打印您的解密祕密,他必須更改代碼並重新編譯,用他自己的密鑰存儲庫簽署他的.apk ,而不是您自己的密鑰存儲庫,從而得不到正確的原始文件。 (「唯一」一點是​​是否可以從您的原始.apk中找出)。

    注:get_my_keyhash_programmatically():

    try { 
        PackageInfo info = getPackageManager().getPackageInfo(
          "el nombre de su paquete por ejemplo com.tarea.u8", 
          PackageManager.GET_SIGNATURES); 
        for (Signature signature : info.signatures) { 
         MessageDigest md = MessageDigest.getInstance("SHA"); 
         md.update(signature.toByteArray()); 
         Log.d("KeyHash:", Base64.encodeToString(md.digest(), Base64.DEFAULT)); 
        } 
    } catch (PackageManager.NameNotFoundException e) { 
    
    } catch (NoSuchAlgorithmException e) { 
    
    } 
    
    +0

    你說「使用工具來加密與k1的祕密 - 例如:https://jwt.io。」但是,當我轉到jwt.io並嘗試使用它從我自己的JSON創建一個令牌時,使用我自己的密鑰(將它放在「祕密」字段中),它只是告訴我祕密是無效的。 「祕密」是它接受的唯一字符串。那麼如何用我自己的密鑰創建一個令牌? – jkane001 2016-03-15 21:12:12

    +1

    @Krypton喜歡什麼?給我一個例子請破解這種方式 – Catalin 2016-03-22 10:49:46

    +4

    經驗豐富的黑客應該在5分鐘內逆轉Java函數encode(),並且他可以發現應用程序的證書散列很容易被用於編碼。使用像XPosed這樣的鉤子框架,他可以在運行時提取應用程序的證書哈希。從此,他使用該散列解碼所有字符串。 – Krypton 2016-03-23 07:55:08