Java客户端.class文件保护

6
我正在构建一个Java EE应用程序的需求阶段,最有可能在GlassFish/JBoss后端上运行(现在不重要)。我知道我不应该在需求时间考虑架构,但人们不禁开始想象组件如何相互连接 :-)
以下是客户端的一些硬性、非灵活的要求: (1)客户端应用程序将是一个Swing框 (2)客户端可以免费下载,但将使用订阅模式(因此需要具有服务器端身份验证/授权等的登录机制) (3)是的,对于这个问题,Java是最好的平台解决方案,原因超出了本帖子的范围 (4)客户端的.class文件需要保护以防反编译
这最后一个(第四个)要求是本文的基础。
我并不真正担心有人实际上会反编译并获取我的源代码:最终只是一些受轻量级业务逻辑驱动的Swing控件。
我担心的是这样的情况:有人反编译我的代码,修改它以利用/攻击服务器,重新编译并启动它。
我已经设想了各种恶劣的解决方案,但不知道这是否是Java EE开发人员普遍面临的问题,并且是否有常见的解决方案。有什么想法吗?
不感兴趣的“代码混淆”技术!
谢谢任何意见!

我其实不太明白...如果认证和授权是在服务器端进行的,那么恶意客户端能做什么呢? - Rekin
@Suirtmed:任何网络浏览器客户端应用程序都是如此。解决方案很简单——使用加密通信(SSL)。基本上,我找不到任何理由来证明代码加密的必要性。 - Rekin
我可以轻松地使用Web代理查看SSL管道上的未加密数据。授权给不受信任用户的调用必须假定它们将受到攻击并适当加固,SSL仅是答案的一部分,并且仅解决未使用数字签名的中间人攻击问题。 - Brian Topping
@Zac,你在stackoverflow上到目前为止使用了哪些搜索词? - Thorbjørn Ravn Andersen
@Rekin 我晚了两周,但无论如何:SSL 只能帮助保护客户端到服务器之间的通信免受攻击者的攻击。如果客户端本身是攻击者,则无济于事。 - sfussenegger
显示剩余3条评论
5个回答

9

您必须假设代码将被反编译并用于利用/攻击服务器。

只信任服务器正在执行的操作。


3
补充一下:@Zac:你应该关注的是如何在服务器上验证用户的身份,因为从理论上讲,攻击者不需要使用你的应用程序就可以造成危害。 - Jeremy

5

我在这里带来一个坏消息。你无法阻止这件事。

我曾经深入研究过JVM,最底层的类加载器必须获取一个未加密的字节流,即类文件。除非用自己的代码替换JVM,否则你无法改变这一点。此外,这里有一个钩子允许查看(复制等)字节流。无论你在更高的级别上做什么,JVM总是会到达这个点并允许访问你的类文件。一旦获取了类文件,它就可以被反编译。混淆技术和工具可以减缓或使其困难,但它们也无法阻止它。

我强烈建议您使用经过验证的安全方法来保护您的服务器。不要将秘密配方嵌入到您提供给客户端的东西中。如果他们足够决心,他们总能找到它。


1
+1。没错。你可能听说过破解Skype通信算法。安全靠混淆是没有安全可言的。 - Rekin
这是一篇很好的文章,也很真实。始终要构建安全、强大的服务器,能够处理来自网络的任何内容。 - bestsss

3
我认为这是一个普遍的“强密码与弱密码”问题:如果知道算法就足以破解消息(即您的登录信息),则密码学是脆弱的。
那么,使用类似OAuth的东西呢?通过与服务器的一次性身份验证过程,客户端应用程序被授予令牌,如果必要,服务器始终可以撤销任何给定客户端的授权。
此外,请注意,身份验证不能替代授权。仅仅因为您的系统认为它知道某人是谁,并不意味着他们应该被授权做任何想做的事情。您还需要部署良好的访问控制,例如JAAS或Spring Security,并将其链接到身份验证。从客户端发出的任何调用的第一项检查是身份验证,第二项检查是该特定客户端是否有权首先进行调用。
无论您采取什么措施,您的服务器都需要根据授权向用户允许调用。

1

使用良好的服务器身份验证,不要在应用程序中存储用户名、密码或加密密钥,正如Rekin所评论的那样,我没有看到你的代码中有什么可以泄露你的服务器保护。

如果您绝对需要加密通信(似乎不是必需的),请使用SSL或任何公钥加密。


0

我有一个独出心裁的解决方案来处理第4点。

我假设你的应用程序具有网络访问权限,因为它在线进行身份验证...

  1. 你有一堆包含类的“jar”文件。唯一的区别是这些类使用对称密钥加密。
  2. 当应用程序启动时,它会在线获取认证,并通过安全连接(例如SSL)获取密钥。
  3. 然后将所有加密文件加载到内存中并对其进行解密。
  4. 接下来创建自定义类加载器,并使用ClassLoader.defineClass将解密后的类加载到类加载器中
  5. 然后您就可以享受代码使用了!

这不是一种具体的方法,而且正如我所说,它是独特的。但是它确实使窃取您的代码变得更加困难。但正如其他帖子中所述,您不能在客户端上隐藏代码中的机密信息。


请查看我上面的答案。我已经进行了详细的调查。不幸的是,它不能保护您。您的自定义类加载器必须在某个时刻将控制权传递给由JVM提供的具体类加载器。钩子总是存在的,在解密之后。 - rfeak
@rfeak - 我完全同意你的观点。 - Paul

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接