在混淆代码中隐藏string

我只是使用proguard模糊我的Android代码,然后反编译它。 有很多string我真的想躲在窥探之下。 当我反编译我的代码string在那里让大家看到…并改变。 其中一个string是我的授权服务器的URL,他们实际上可以改变URL指向一个假的服务器(因为我将释放服务器代码给公众)。 隐藏这种信息的最好方法是什么?

另外,我注意到R类string都是随机数字,但是在反编译的代码中我找不到R类。 它在哪里?

敌人的例子,我看到: new SimpleCursorAdapter(localActivity, 2130903058, localCursor, arrayOfString, arrayOfInt);

2130903058是一个布局文件,但它是什么引用? 数字意味着什么,除非它指向某种地址。

假设你对隐晦而不是安全感到高兴,那么你可以使用一些机制,但像proguard这样的混淆器不能帮助你。

为了达到这个目的,你需要自己对string进行编码或者encryption,你使用的方法取决于你想要防御的东西,如果你只是试图隐藏明显的检查,那么编码就足够了(参见android .util.Base64, http://developer.android.com/reference/android/util/Base64.html )。 请注意,编码是在没有办法保证,它会去除明显的引用到您的网站。

如果你试图防御更多的东西,那么你可以移动到实际encryption的string,做到这一点,你会使用对称密码像AES通过javax.crypto.Cipher, http: //www.androidsnippets.org/snippets/ 39 / index.html提供了一个体面的使用示例。 再次,这是更恼人的,然后安全的黑客,因为你将需要存储在你的jar子里的密钥,从而否定任何encryption安全。

为了更清楚地说明,基本的步骤是:

  1. 手动创build使用已知密钥encryption您的string。
  2. 将您的代码转换为使用此string的解密版本,例如:

之前:

 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); ... } 

所有这一切的(好)替代scheme正在考虑使用第三方DRM解决scheme,如谷歌提供的许可服务器http://android-developers.blogspot.com/2010/07/licensing-service-for-android.html 。 这可能比你推出自己的东西更安全,但是受到与我上面描述的非常类似的限制。

大家好。

  1. secret成为你想要隐藏的文本

  2. finddebug / release.keystore的keyhash。 让k1是这个关键。

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

  1. 使用一个工具(在android代码外部)用k1encryptionsecret

    encrypted = encode (secret, k1)

(例如: https : //jwt.io ,对于java: https : //github.com/jwtk/jjwt )。

  1. 在你的android java代码中encrypted写下来。 当你需要解密版本的encrypted (这是原来的secret )写的

original = decode(encrypted, get_my_keyhash_programmatically() )

就这样。 这是有效的,因为原始的secret没有显示在java源代码上, k1也没有对它进行解码。 而且,如果黑客想要打印你的解密秘密,他必须更改代码并重新编译,用他自己的密钥库签名他的.apk,而不是你自己的密钥库,因此没有得到正确的原始secret 。 (“唯一的一点”是k1是否可以从您的原始.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) { } 

我所做的是在我的全局实用程序类中创build一长串静态string。 在很长的string列表中的某个位置,我把我的密钥分成多个块。

用我的代码很容易看到真正的密码是什么 – 但是一旦混淆器开始工作,所有的静态都会有A,B,C等名称,而且不容易再发现。

我用了ROT47。 这不是很安全,但易于使用和实施,因为它是一个对称的编码器/解码器

你应该谷歌“只是另一个Perl黑客”。 这些程序是用混淆的代码打印出一个string。 网上还有很多其他语言的例子,比如Perl。

维基百科条目

您可以使用DexGuard来encryptionstring,可能比手动实现更有效,而且不会增加源代码的负担。