18

我正在研究必须保护数据(显示代码不是主要问题)文件的项目。我们正在使用 Java + Netbeans。是否有任何工具可以创建加密格式的 jar?我们也将 sqlite 用于数据库 - 因此将文本文件以加密格式放置对我们来说也是不合适的选择。

4

6 回答 6

23

创建加密的 JAR 是不可能的,因为正在执行的 JavaVM 必须能够以某种方式读取它想要执行的数据。与虚拟机类似,任何拥有适当工具和专业知识的人都可以从 JAR 中提取所有数据。

如果可以加密 JAR,您还必须向想要执行 JAR 的客户端提供一些解密密钥或工具,这完全违背了加密的目的。

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

于 2009-02-11T16:36:44.197 回答
9

Kosi2801 几乎是正确的。我能想到你唯一能做的就是以下,但这很丑陋。

  1. 运送一个小的标准 JAR 和一个加密的数据文件。
  2. 当 JAR 运行时,它将(一些)加密数据文件解密到内存中(就像 JAR 中数据所在的目录,基本上是一个简单的指针/长度对的内存文件系统)
  3. 设置你自己的类加载器,当被调用时,从 JAR 中获取正确的加密字节(使用 #2 中描述的伪 FS 表),解密它,然后从那里加载类数据

这将让您加载类。你可以做同样的事情(没有类加载器)来加载其他资源。

虽然实现起来很有趣(对于那些喜欢挑战的人来说),但有一些问题:

  1. 您需要能够解密这些内容,因此用户必须每次都输入密码或类似的东西。如果 JAR 知道足以解密它自己,那么任何人都可以查看它并弄清楚如何解密。这可以通过通过 Internet 联系已知良好的服务器以请求解密密钥来缓解(只要您使该过程安全)。当然,任何时候有人想要运行程序都需要一个有效的网络连接。
  2. 一切都在记忆中结束。如果没有处理微小位加密字节码的自定义 JVM(正如 Cameron McKay 所提到的),这些类最终会在某个时刻被解密并存放在主内存中。除非您依靠操作系统来阻止其他人读取该内存,否则您已经输给了任何有一点时间的人。您尝试从某些加密存储中读取的资源(例如图像/字体/等)的相同问题。

所以你可以给人们绕路,让事情变得更难,但在你已经给予的情况下,你所能做的就是试图让其他人不得不投入的时间变得不值得。

软件保护很困难,尤其是像 Java 这样的东西,它可以很容易地被反编译,并且不能像 C/Assembly 那样改变它自己的代码。有一些最昂贵的软件需要硬件加密狗或锁定到某个 CPU 或其他硬件是有原因的。

于 2009-02-11T20:38:03.147 回答
9

我同意 Kosi2801。类文件加密只是对安全性的模仿(参见http://www.excelsior-usa.com/articles/java-obfuscators.html) 使用自定义类加载器可能会破坏应用程序,例如在应用程序服务器中。

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

最安全的方法是在 JavaCard 等外部​​设备上存储和执行部分字节码。

注意,我是 Licel LLC 的首席执行官。Stringer Java 混淆器的开发者。

于 2012-05-10T11:58:47.467 回答
4

一般来说,如果您希望应用程序及其数据是独立的,则无法以安全的方式执行此操作。但是,您当然可以加密文件并使用隐藏在代码中的密钥对其进行解密。一个坚定的黑客可以得到它,但如果这不是你所担心的,那很好。如果您这样做,请记住加密数据无法压缩,因此请先压缩,然后再加密。

如果您确实需要确保数据安全(例如机密数据),您将需要使用密钥加密数据并通过某些外部方式将该密钥提供给应用程序,例如将其放在拇指驱动器上并将其发送到用户通过安全的快递。

另一种可能性是通过 SSL 使数据(或密钥)可用,并使用良好的身份验证方法来验证您的用户是谁。

一般来说 - 任何系统都不可能完全安全,但也不是必需的。系统只需要足够安全以阻止您认为会试图破解它的攻击者。

于 2009-02-15T09:57:41.797 回答
3

另一种选择是制作一个自定义 JVM,它可以即时解密 JAR。但同样的问题仍然存在:在某些时候,JAR Java 类必须被解密才能由 JVM 运行,并且此时它们可以被捕获和反编译。

更不用说拥有自定义 JVM 将要求所有用户也下载该 JVM。

于 2009-02-11T16:53:14.093 回答
2

您可以使用 CipherOutputStream 和 CipherInputStream 以加密格式将 Java 对象序列化到磁盘。这可能是一个用于保存数据的选项。

于 2009-02-11T17:17:21.523 回答