如何创建加密的Jar文件?

18

我正在处理一个必须要保护数据文件的项目(揭示代码不是主要问题)。我们使用Java + Netbeans. 有没有什么工具可以创建加密格式的jar包?我们还使用sqlite作为数据库 - 所以将文本文件放在加密格式中对我们来说也不是适当的选择。


5
你的设计存在问题;将敏感数据与代码一起发送并不是一个聪明的想法。 - Rob
这是一个桌面应用程序。使用Java实现跨平台兼容性。 - Kartik Mistry
3
如果您需要保护数据,请考虑使用SqlCipher。如果您愿意,可以将加密后的数据库文件直接交付。 - Hot Licks
Ark支持创建加密的Jar归档文件。 - noraj
6个回答

23

创建加密的 JAR 文件是不可能的,因为执行 JavaVM 必须能够读取要执行的数据。就像虚拟机一样,任何具备适当工具和技能的人都可以从 JAR 中提取所有数据。

如果可以加密 JAR 文件,您还必须向想要执行 JAR 的客户端提供某些解密密钥或功能,这会完全破坏加密的目的。

你能得到的最好的办法是混淆,但这对于有野心的攻击者来说并不是真正的安全障碍。


9

我赞同Kosi2801的观点。类文件加密只是模拟安全性(参见http://www.excelsior-usa.com/articles/java-obfuscators.html)。

使用自定义的ClassLoader可能会破坏应用程序,例如在应用服务器中。

有更好的方法:对类文件中的字符串常量进行加密。大多数商业混淆器都有此功能,例如AllatoriStringer Java Obfuscation ToolkitZelix KlassMasterSmokescreenDashO(超级昂贵)。Stringer Java Obfuscator具有调用上下文检查和完整性控制功能,使保护难以被破解。

最安全的方式是将部分字节码存储并执行在外部设备上,例如JavaCard。

注:我是Licel LLC的CEO。Stringer Java Obfuscator的开发者。


该链接已经不存在了。 - Ali Bigdeli

9
Kosi2801说得基本正确。我能想到的唯一解决方案就是下面这个,但它很丑陋。
  1. 提供一个小型标准JAR和一个加密数据文件。
  2. JAR 运行时将(某些)加密数据文件解密到内存中(比如:指向/长度对的简单内存文件系统中的数据目录)
  3. 设置自己的类加载器,在调用时从JAR获取正确的加密字节(使用#2中描述的伪FS表),解密后从那里加载类数据。
这样就可以加载类了。你可以做同样的事情(不需要类加载器)来加载其他资源。
虽然实现起来有趣(对于喜欢挑战的人来说),但这个方法也存在一些问题:
  1. 你需要能够解密文件,所以用户每次要么需要输入密码,要么使用类似的方式。如果JAR知道如何解密,那么任何人都可以查看它并找出如何解密的方法。通过在互联网上联系已知的好服务器请求解密密钥(只要使该过程安全),可以缓解这个问题。当然,这需要一个活动的"网"连接,任何时候只要有人想运行程序。
  2. 所有东西都在内存中。除非有一个自定义的 JVM 处理微小的加密字节码(如 Cameron McKay 所提到的),否则类最终会以明文形式出现在内存中。除非您依赖操作系统防止其他人读取该内存,否则对于任何稍有空闲时间的人来说,您已经输掉了竞赛。对于尝试从某些加密存储中读出的资源(如图像/字体等)也面临同样的问题。
因此,你可以给别人带来麻烦,让事情更难一些,但在你所描述的情况下,你所能做的就是使对方投入的时间不值得。 软件保护很难,特别是在像 Java 这样的编程语言中,它容易被反编译,并且无法像 C/Assembly 那样改变自己的代码。这就是为什么一些最昂贵的软件需要硬件加密狗或锁定到某个 CPU 或其他硬件的原因。

现在我明白为什么我使用Ericsson TEMS时必须始终使用USB dongle来运行它了,令人惊讶的是,USB上没有数据,但如果没有它,它就无法工作。 - Johnydep

4
一般情况下,如果您希望应用程序及其数据是自包含的,那么没有安全的方式来实现此目标。但是,您可以将文件加密并使用在代码中隐藏的密钥进行解密。坚定的黑客可以获得它,但如果这不是您担心的问题,那就没关系了。如果您这样做,请记住,加密数据无法压缩,因此请先压缩,然后再加密。
如果您真正需要数据是安全的(例如,保密数据),则需要使用密钥对数据进行加密,并通过某些外部手段向应用程序提供该密钥,例如将其放在存储器上,然后通过安全快递将其交付给用户。
另一种可能性是通过SSL公开数据(或密钥),并使用良好的身份验证方法验证用户身份。
总的来说,任何系统都不能完全安全,但这也不是必要的。系统只需要足够安全,以防止您认为会试图破解它的攻击者。

3
另一种选择是制作一个自定义JVM,在运行时解密JAR文件。但是同样的问题仍然存在:在某个时刻,JAR Java类必须被解密才能被JVM运行,而此时它们可以被捕获和反编译。
更不用说拥有一个自定义JVM将需要所有用户也下载该JVM。

2
您可以使用CipherOutputStream和CipherInputStream将Java对象序列化为加密格式并保存到硬盘上。这可能是一种保存数据的选择。

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