我想知道是否有人在他自己的商业产品上使用商业/免费java混淆器。我只知道一个项目实际上在发布的ant构建步骤中有一个混淆步骤。
你混淆了吗?如果是这样,你为什么要混淆?
它真的是一种保护代码的方式,还是对开发人员/经理来说是一种更好的感觉?
编辑:好的,我确切地说明了我的观点:您是否为了保护您的IP(您的算法,您投入产品的工作)而进行模糊处理?出于安全原因,我不会混淆,这感觉不对。所以我只是谈论保护你的应用程序代码免受竞争对手。
@staffan有一个好点:
远离链接代码流的原因是其中一些更改使JVM无法有效地优化代码。实际上,它实际上会降低应用程序的性能。
答案 0 :(得分:60)
如果您进行模糊处理,请远离通过更改代码流和/或添加异常块来修改代码的混淆器等,以使其难以反汇编。为了使代码不可读,通常只需更改方法,字段和类的所有名称。
远离更改代码流的原因是其中一些更改使JVM无法有效地优化代码。实际上,它实际上会降低应用程序的性能。
答案 1 :(得分:25)
我认为混淆的旧(经典)方式正在逐渐失去其相关性。因为在大多数情况下,经典的混淆器会破坏堆栈跟踪(它不利于支持您的客户)
如今主要要点是不保护某些算法,而是保护敏感数据:API登录/密码/密钥,负责许可的代码(盗版仍在这里,特别是西欧,俄罗斯,亚洲,恕我直言),广告帐号ID等。
有趣的事实:我们在Strings中拥有所有这些敏感数据。实际上,Strings约占我们应用程序逻辑的50-80%。 在我看来,混淆的未来是“字符串加密工具”。
但现在“字符串加密”功能仅适用于商业混淆器,例如:Allatori,Zelix KlassMaster,Smokescreen,Stringer Java Obfuscation Toolkit,DashO。
N.B。 我是Licel LLC的首席执行官。 Stringer Java Obfuscator的开发人员。
答案 2 :(得分:17)
我使用proguard进行JavaME开发。它不仅非常擅长使jar文件更小(对移动设备至关重要),而且它可以作为一种更好的方式来执行特定于设备的代码,而无需使用IDE不友好的预处理工具,如天线。
E.g。
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");
}
}
这会被编译,混淆,并且类文件最终会像你写的那样结束:
public void doSomething()
{
System.out.println("This is a motorola phone");
}
因此,您可以使用代码变体来解决JVM /库实现中的制造商错误,而无需填充最终的可执行类文件。
我相信某些商业混淆器在某些情况下也可以合并类文件。这很有用,因为你拥有的类越多,zip(jar)文件中的大小开销就越大。
答案 3 :(得分:13)
今年我花了一些时间尝试各种Java混淆器,我发现其中一个远远超过其余部分:JBCO。不幸的是,设置起来有点麻烦,并且没有GUI,但就其产生的混淆程度而言,它是无与伦比的。你试着给它一个简单的循环,如果你的反编译器没有崩溃试图加载它,你会看到这样的东西:
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支持它们=)
答案 4 :(得分:13)
我使用ProGuard并强烈推荐它。虽然混淆确实可以保护您的代码免受偶然攻击者的攻击,但它的主要好处是可以最大限度地减少删除未使用的类和方法以及将所有标识符缩短为1或2个字符的效果。
答案 5 :(得分:12)
我认为在大多数情况下,混淆是没有意义的:即使使用完整的源代码,通常也很难弄清楚它的意图是什么(假设没有注释,并且没有有意义的局部变量名称 - 这是从字节代码重新生成源的情况)。混淆只是装饰蛋糕。
我认为开发人员,特别是他们的经理往往过分夸大某人看到源代码的风险。虽然好的反编译器可以产生漂亮的源代码,但使用它并不容易,而且相关的成本(更不用说法律风险)足以使这种方法很少有用。我只是反编译来调试闭源供应商产品的问题(DB抽象层中的死锁,呃)。 我认为Bytecode实际上是混淆的,但我们仍然发现了潜在的问题 - 这是一个实际的设计问题。
答案 6 :(得分:7)
我想这真的归结为你的Java代码是什么,它是如何分布的以及你的客户是谁。我们不会混淆任何东西,因为我们从来没有找到一个特别好的东西,它往往比它的价值更麻烦。如果有人可以访问我们的JAR文件并且知道能够在他们内部嗅探,那么他们可以做的就是扯掉我们的源代码,这是令人担忧的事情。