我想知道是否有人在自己的商业产品上使用了商业/免费的Java混淆器。 我只知道一个项目在发布的ant构建步骤中实际上具有混淆步骤。
你会混淆吗? 如果是这样,为什么还要混淆?
这真的是保护代码的一种方法,还是对开发人员/管理人员来说是一种更好的感觉?
编辑:好的,我的意思是确切的:您是否为保护IP(您的算法,产品中投入的工作)而感到困惑? 我不会因为安全原因而混淆,这感觉不对。 因此,我只是在谈论保护您的应用程序代码不受竞争对手的侵害。
@staffan有一个好处:
The reason to stay away from chaining code flow is that some of those changes makes it impossible for the JVM to efficiently optimize the code. In effect it will actually degrade the performance of your application.
如果进行混淆,请远离混淆器,这些混淆器会通过更改代码流和/或添加异常块来修改代码,从而使代码难以分解。为了使代码不可读,通常只需更改方法,字段和类的所有名称即可。
避免更改代码流的原因是,其中一些更改使JVM无法有效地优化代码。实际上,它实际上会降低应用程序的性能。
我认为混淆的旧方法(古典方法)正在逐渐失去其意义。 因为在大多数情况下,经典的混淆器破坏了堆栈跟踪(不利于支持客户)
如今,重点不是保护某些算法,而是保护敏感数据:API登录名/密码/密钥,负责许可的代码(盗版仍在这里,尤其是西欧,俄罗斯,亚洲,恕我直言),广告帐户ID等 。
有趣的事实:我们在Strings中拥有所有这些敏感数据。 实际上,字符串大约占我们应用程序逻辑的50-80%。
在我看来,混淆的未来是"字符串加密工具"。
但是现在,"字符串加密"功能仅在商业混淆器中可用,例如:Allatori,Zelix KlassMaster,Smokescreen,Stringer Java混淆工具包,DashO。
N.B.
我是Licel LLC的首席执行官。 Stringer Java Obfuscator的开发人员。
我将proguard用于JavaME开发。它不仅非常擅长使jar文件更小(对于移动设备必不可少),而且还可以作为一种更好的方式来执行特定于设备的代码,而无需诉诸于IDE不友好的预处理工具(如天线)。
例如。
1 2 3 4 5 6 7 8 9 10 11 12
| public void doSomething()
{
/* Generated config class containing static finals: */
if (Configuration.ISMOTOROLA)
{
System.out.println("This is a motorola phone");
}
else
{
System.out.println("This is not a motorola phone");
}
} |
这将被编译,混淆,并且类文件最终就像您编写的那样结束:
1 2 3 4
| public void doSomething()
{
System.out.println("This is a motorola phone");
} |
因此,您可以使用多种代码来解决JVM /库实现中的制造商错误,而无需扩展最终的可执行类文件。
我相信有些商业混淆器在某些情况下也可以将类文件合并在一起。这很有用,因为您拥有的类越多,zip(jar)文件中的开销就越大。
我使用ProGuard并强烈推荐它。尽管混淆确实可以保护您的代码不受偶然攻击者的侵害,但其主要好处是,可以最大限度地减少删除未使用的类和方法并将所有标识符缩短为1或2个字符的影响。
我今年花了一些时间尝试各种Java混淆器,而我发现其中的一个比其他混淆器要先进得多:JBCO。不幸的是,它的设置有点麻烦,并且没有GUI,但是就其产生的混淆程度而言,它是无与伦比的。您尝试将其馈入一个简单的循环,并且如果您的反编译器在尝试加载它时不会崩溃,则会看到以下内容:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| if(i < ll1) goto _L6; else goto _L5
_L5:
char ac[] = run(stop(lI1l));
l7 = (long)ac.length << 32 & 0xffffffff00000000L ^ l7 & 0xffffffffL;
if((int)((l7 & 0xffffffff00000000L) >> 32) != $5$)
{
l = (long)III << 50 & 0x4000000000000L ^ l & 0xfffbffffffffffffL;
} else
{
for(l3 = (long)III & 0xffffffffL ^ l3 & 0xffffffff00000000L; (int)(l3 & 0xffffffffL) < ll1; l3 = (long)(S$$ + (int)(l3 & 0xffffffffL)) ^ l3 & 0xffffffff00000000L)
{
for(int j = III; j < ll1; j++)
{
l2 = (long)actionevent[j][(int)(l3 & 0xffffffffL)] & 65535L ^ l2 & 0xffffffffffff0000L;
l6 = (long)(j << -351) & 0xffffffffL ^ l6 & 0xffffffff00000000L;
l1 = (long)((int)(l6 & 0xffffffffL) + j) & 0xffffffffL ^ l1 & 0xffffffff00000000L;
l = (long)((int)(l1 & 0xffffffffL) + (int)(l3 & 0xffffffffL)) << 16 & 0xffffffff0000L ^ l & 0xffff00000000ffffL;
l = (long)ac[(int)((l & 0xffffffff0000L) >> 16)] & 65535L ^ l & 0xffffffffffff0000L;
if((char)(int)(l2 & 65535L) != (char)(int)(l & 65535L))
{
l = (long)III << 50 & 0x4000000000000L ^ l & 0xfffbffffffffffffL;
}
}
}
} |
您不知道Java拥有goto吗?好吧,JVM支持它们=)
我认为在大多数情况下,混淆是没有意义的:即使使用完整的源代码,通常也很难弄清楚到底是什么意思(假设没有注释,并且没有局部变量的有意义的名称,当重新编??译时就是这种情况) -从字节码生成源)。混淆只是装饰蛋糕。
我认为开发人员,尤其是他们的经理往往会过度夸大有人看到源代码的风险。好的反编译器可以生成漂亮的源代码,但使用它并不是一件容易的事,并且相关的成本(更不用说法律风险)高得足以使这种方法很少有用。我只是反编译用于调试闭源供应商产品的问题(数据库抽象层中的死锁,呃)。
我认为字节码实际上是令人困惑的,但尽管如此,我们仍然发现了潜在的问题-这是一个实际的设计问题。
我想这实际上取决于您的Java代码是什么,它如何分布以及您的客户是谁。我们不会混淆任何事情,因为我们从来没有发现过特别出色的东西,而且它往往会带来比其价值更大的麻烦。如果某人可以访问我们的JAR文件,并且具有能够在其中进行嗅探的知识,那么与剥夺我们的源代码相比,他们可以做的事情要多得多。