隐藏在混淆代码中的字符串

我只是使用proguard对我的Android代码进行了混淆,然后对其进行了反编译。 有许多字符串我真的想隐藏在窥探的眼睛里。 当我反编译我的代码时,每个人都可以看到字符串……并进行更改。 其中一个字符串是我的许可服务器的URL,它们实际上可以将URL更改为指向虚假服务器(因为我将向公众发布服务器代码)。 隐藏此类信息的最佳方法是什么?

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

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

2130903058是一个布局文件,但它引用了什么? 除非它指向某种地址,否则该数字没有任何意义。

假设你对晦涩而不安全感到满意,你可以使用许多机制,但像proguard这样的混淆器无法帮助你。

要实现这一点,你需要自己对字符串进行编码或加密,你使用的方法取决于你要防范的内容,如果它只是试图隐藏明显的检查,那么编码可能就足够了(请参阅android .util.Base64, http://developer.android.com/reference/android/util/Base64.html )。 请注意,编码是在NO WAY SECURE中完成的,它将删除对您站点的明显引用。

如果你想要防范更多东西,那么你可以转向实际加密字符串,为此你可以使用像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 = ""; private String key = " 

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

大家好。

  1. secret成为你想隐藏的文字

  2. 找到debug / release.keystore的keyhash。 设k1为此键。

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

  1. 使用工具(android代码外部)用k1加密secret

    encrypted = encode (secret, k1)

(例如: https : //jwt.io,for 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) { } 

我所做的是在我的全局实用程序类中创建一长串静态字符串。 在长字符串列表中的某个地方,我把密钥放在多个块中。

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

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

你应该谷歌“只是另一个Perl黑客”。 这些是使用混淆代码打印出字符串的程序。 其他语言中也有很多例子,然后是网上的Perl。

维基百科条目

您可以使用DexGuard加密字符串,可能比您手动实现的更有效,并且不会增加源代码的负担。