2010-12-13 212 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