jvm 如何锁定已编译的Java类以防止反编译?

toe95027  于 2022-12-18  发布在  Java
关注(0)|答案(9)|浏览(190)

如何锁定已编译的Java类以防止反编译?
我知道这一定是网上讨论得很好的主题,但我在参考了他们之后无法得出任何结论。
许多人确实建议使用模糊处理器,但他们只是用难以记忆的字符序列重命名类、方法和字段,但敏感的常量值呢?
例如,您已经开发了基于密码加密技术的加解密组件,现在任何普通Java人员都可以使用JAD反编译类文件并轻松检索密码值(定义为常量)以及salt,然后通过编写独立的小程序来解密数据!
或者,这些敏感组件是否应该构建在本机代码(例如VC++)中,并通过JNI调用它们?

9q78igpj

9q78igpj1#

一些更高级的Java字节码混淆器所做的远不止是类名的篡改。例如,Zelix KlassMaster还可以以一种使代码流很难遵循的方式扰乱代码流,并作为一个优秀的代码优化器工作。
另外,许多模糊处理器还能够对字符串常量进行置乱,并删除未使用的代码。
另一种可能的解决方案(不一定排除模糊处理)是使用encrypted JAR files和一个定制的类加载器来进行解密(最好使用本机运行时库)。
第三(可能提供最强的保护)是使用本机提前编译器,例如GCCExcelsior JET,它们将Java代码直接编译为特定于平台的本机二进制代码。
在任何情况下,你必须记住,正如爱沙尼亚的谚语“锁是动物”。意思是每一位代码都是可用的(加载到内存中)在运行时,并给予足够的技能,决心和动机,人们可以并将反编译,解扰和黑客您的代码...你的工作只是让这个过程不舒服,你可以,但仍然保持工作...

v64noz0r

v64noz0r2#

只要用户能够访问加密数据和解密软件,基本上就不可能做到完全安全。以前解决这个问题的方法是使用某种形式的外部黑盒来处理加密/解密,如加密狗、远程身份验证服务器等。但即使这样,考虑到用户可以完全访问自己的系统,这只会使事情变得困难。并非不可能-除非你能将你的产品直接与存储在“黑匣子”中的功能联系起来,比如说,在线游戏服务器。

rks48beu

rks48beu3#

免责声明:我不是安全Maven。
这听起来是个坏主意:你让别人用你给予他的“隐藏”密钥加密东西。我不认为这是安全的。
也许不对称的钥匙也可以:

  • 使用公钥部署加密许可证以进行解密
  • 让客户创建新许可证并将其发送给您进行加密
  • 将新的许可证发送回客户端。

我不确定,但我相信客户端可以用你给他的公钥加密许可证密钥,然后你可以用你的私钥解密并重新加密。
您可以为每个客户保留一个单独的公钥/私钥对,以确保您实际上是从正确的客户那里获得东西-现在 * 您 * 对密钥负责...

au9on6nz

au9on6nz4#

不管你做什么,它都可以被“反编译”。见鬼,你可以直接反汇编它。或者查看内存转储来找到你的常量。你看,计算机需要知道它们,所以你的代码也需要知道。
对此该怎么办?
尽量不要将密钥作为代码中的硬编码常量提供:保留它作为每个用户的设置。让用户负责保管这个密钥。

klsxnrf1

klsxnrf15#

@jatanp:或者更好的是,他们可以反编译,删除许可代码,并重新编译。对于Java,我真的不认为有一个适当的,防黑客的解决方案来解决这个问题。甚至一个邪恶的小加密狗也不能阻止Java。
我自己的业务经理担心这个问题,我想得太多了。但是话又说回来,我们把我们的应用程序卖给了大公司,他们倾向于遵守许可条件--通常是一个安全的环境,这要归功于会计师和律师。如果你的许可写得正确,反编译行为本身可能是非法的。
所以,我不得不问,你真的需要像你为你的应用程序寻求的那样的强化保护吗?你的客户群是什么样的?(企业?还是青少年游戏玩家大众,这将是一个更大的问题?)

wvmv3b1j

wvmv3b1j6#

如果你正在寻找一个许可证解决方案,你可以看看TrueLicense API。它基于非对称密钥的使用。然而,这并不意味着你的应用程序不能被破解。每一个应用程序都可以通过足够的努力被破解。真正重要的是,正如斯图回答的那样,弄清楚你需要多强的保护。

jdg4fx2g

jdg4fx2g7#

您可以毫无顾虑地使用字节码加密。
事实上,上面引用的论文《破解Java字节码加密》包含了一个逻辑谬误,论文的主要主张是 * 在运行之前,所有的类都必须被解密并传递给ClassLoader.defineClass(...)方法 *,但事实并非如此。
这里忽略的假设是 * 假设它们在可信的或标准的java运行时环境中运行 *。没有任何东西可以强制受保护的java应用程序不仅启动这些类,而且甚至解密并将其传递给ClassLoader。换句话说,如果您使用标准JRE,则无法拦截defineClass(...)方法,因为标准java没有用于此目的的API。如果你使用修改过的JRE加上补丁ClassLoader或其他“黑客伎俩”,你就不能这么做,因为受保护的java应用程序根本无法工作,因此你就没有什么可拦截的。而且绝对不重要的是,黑客使用的是哪个“补丁查找器”或哪个伎俩。这些技术细节是一个完全不同的故事。

9jyewag0

9jyewag08#

我不认为有什么有效的离线反盗版方法。视频游戏行业已经尝试了很多次,他们的程序总是被破解。唯一的解决办法是程序必须在线运行,连接到您的服务器,以便您可以验证lincence密钥,而且被许可方一次只有一个活动的连接。这就是X1 E0 F1 X或X1 E1 F1 X的工作原理。更坚韧的是,还有为他们开发的私人服务器可以绕过安全措施。
话虽如此,我不相信中/大型公司使用非法复制的软件,因为他们的许可证的成本是最低的(也许,我不知道你要为你的程序收取多少费用)相比,试用版的成本。

igsr9ssn

igsr9ssn9#

问:如果我加密我的.class文件并使用一个定制的类加载器来动态加载和解密它们,这会阻止反编译吗?
答:防止Java字节码反编译的问题几乎和语言本身一样古老。尽管市场上有一系列的混淆工具,但初学Java的程序员仍在不断地思考新的聪明的方法来保护他们的知识产权。在这一期Java问答中,我将澄清一些关于一个经常在论坛中反复提及的想法的神话。
Java .class文件可以极其容易地重构为与原始文件非常相似的Java源代码,这与Java字节码设计目标和权衡有很大关系。除其他外,Java字节码设计的目的是紧凑性、平台独立性、网络移动性以及易于通过字节码解释器和JIT进行分析(即时)/HotSpot动态编译器。可以说,编译后的.class文件非常清楚地表达了程序员的意图,因此比原始源代码更容易分析。
如果不能完全阻止反编译,至少可以做几件事来增加反编译的难度。例如,作为编译后的步骤,您可以修改.class数据,使字节码在反编译时更难读取,或者更难反编译成有效的Java代码(或两者)。像执行极端方法名重载这样的技术对于前者工作得很好,和操纵控制流来创建无法用Java语法表示的控制结构,这些技术在后一种情况下效果很好。2比较成功的商业混淆器混合使用了这些技术和其他技术。
不幸的是,这两种方法实际上都必须更改JVM将运行的代码,许多用户对此感到担心(这是正确的),这样转换可能会给应用程序增加新的bug。此外,方法和字段重命名可能会导致反射调用停止工作。更改实际的类和包名称可能会破坏其他几个JavaAPI(JNDI(Java命名和目录接口)、URL提供者等)。除了改变的名称之外,如果类字节码偏移和源代码行号之间的关联被改变,则恢复原始异常堆栈跟踪可能变得困难。
还有一个选项是混淆原始的Java源代码。但从根本上说,这会导致一系列类似的问题。加密,而不是混淆?
也许上面的内容让您想到,“好吧,如果我不操作字节码,而是在编译后加密所有的类,并在JVM中动态地解密它们(这可以通过定制的类加载器来完成),然后JVM执行我的原始字节码,但没有什么需要反编译或反向工程,对吗?”
不幸的是,如果你认为你是第一个提出这个想法的人,或者你认为它实际上是有效的,你就错了,原因与你的加密方案的强度无关。

相关问题