逆向工程是android apk的一个很大的问题。任何人都可以使用dex2jar和jd轻松地从apk文件生成代码。 Proguard可以通过更改变量/方法名称来提供一点安全性。问题是.so文件。举个例子,我有一个so文件,里面有加密和解密方法。如果有人获得我的apk,那么他可以轻松获得so文件,并通过创建一个具有相同包名称的新项目(不隐藏在本机加载类中),他可以毫无问题地使用这些函数。
有什么办法可以防止这种情况吗?有没有办法让我可以从本机代码中识别我的项目,如果它来自无效项目,则拒绝该请求? Eclipse使用密钥库和密码对apk进行签名。我可以从本机代码检查签名信息吗?
答案 0 :(得分:1)
我的2美分是Proguard
只是一个基本的混淆器(直到某一点)。还有许多其他服务/工具(可能不是完全免费的),但要做好混淆,应用程序完整性保护,篡改检测和篡改防御等。查看Arxan和DashO Pro。
您可能会尝试使用它们来获得更多保护。他们甚至使用root设备。希望这在某种程度上有所帮助。
答案 1 :(得分:1)
这是任何中间字节码语言的经典问题:JVM语言(Java,Groovy,Akka等),CLR语言(C#,ASP.NET等)等等。由于将源代码编译为其中间字节码的过程已经充分记录并且相当直接,因此将字节码反向工程回到源代码并不是那么困难。
正如@Shobhit Puri已经指出的那样,一个好的混淆器将帮助阻止大多数潜在的攻击者消耗能量来反编译你的字节码。但任何具有足够技能的坚定攻击者都能够对任何混淆代码进行逆向工程(请注意,有很多高质量Java de-obfuscators可以生成。)
您最好的选择是在服务器上存储任何敏感资源或业务逻辑,让客户端(您的Android应用)访问这些资源或以防御方式调用该业务逻辑。通过“防御性”,我的意思是您对客户端进行编码,使得成功获取完整源代码的任何攻击者都无法确定任何有意义的攻击者。
例如,而不是:
// Get password from user input:
String password = getUserInput();
// Make sure password is correct.
if(password.equals("12345") {
// Grant access to the system
} else {
throw new SecurityException("Blah whatever");
}
你有这个:
// Get password from user input:
String password = getUserInput();
// Make sure password is correct.
String correctPassword = passwordService.fetchFromServer();
if(password.equals(correctPassword) {
// Grant access to the system
} else {
throw new SecurityException("Blah whatever");
}
如果攻击者能够访问您的源代码,并且您在客户端的某个地方提供了密码访问权限(即使它已加密),最终他们将会弄清楚如何进入。但是如果您获取来自服务器的神奇密码,永远不会在客户端的任何地方引用它的值,然后他们现在需要进入你的服务器才能访问它。
然后你所要做的就是妥善保护你的应用服务器,为此你有很好的前景,如:
请注意,在我上面的代码示例中,最终没有完全防御熟练的攻击者。例如,熟练的攻击者可以在passwordService#fetchFromServer()
呼叫期间嗅探客户端和服务器之间的网络流量。如果密码以明文形式返回,瞧 - 他们有。即使使用SSL或其他强加密返回密码,您的客户端也需要在本地某处存储或访问该加密的私钥。一旦他们拥有私钥,他们就能够访问密码。这一切都说:
没有完美的安全性。没有不可攻击的系统这样的东西。 您的安全性的目的应该是使获取资源的成本远远大于资源本身的价值。
作为一名聪明的开发人员,您需要假设攻击者将以各种方式利用您的客户端应用程序。您需要假设他们最终将获得对客户端源代码的访问权限,甚至了解它与服务器的通信方式。在服务器端,您需要假设来自客户端的每个请求都是攻击,并将其视为攻击。这将使您处于正确的防御性编码状态。
您需要加强的是服务器端安全性,这无论如何都是微不足道的。但是,如果您只记得将所有敏感代码和数据保存在服务器上,并在客户端以防御方式访问它,那么您将为保护您的应用程序做更多的工作,而不是任何混淆器可以为您提供。 HTH和快乐的编码。