Java 如何创建加密的 Jar 文件?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/537596/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 15:58:20  来源:igfitidea点击:

How to create encrypted Jar file?

javasqliteencryptionjar

提问by Kartik Mistry

I am working on project that must need to protect data (revealing code is not main problem) files. We are using Java + Netbeans. Is there any facility that will create jar in encrypted format? We are also using sqlite for database - so putting text file in encrypted format is not proper option for us too.

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

回答by Kosi2801

Creating encrypted JARs is not possible, since the executing JavaVM has to somehow be able to read the data it wants to execute. And similar to a VM it would be possible for anyone with the proper tools and know-how to extract all data from the JAR.

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

If it would be possible to encrypt the JAR, you would also have to provide some decryption-key or facility to the client which wants to execute the JAR which defeats the purpose of encryption at all.

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

The best you can get is obfuscation, but that's no real security or hurdle for the ambitious attacker.

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

回答by cdmckay

Another option would be to make a custom JVM that decrypted the JAR on the fly. But the same problem remains: at some point the JAR Java classes have to be decrypted to be run by the JVM, and at that point they can be captured and de-compiled.

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

Not to mention that having a custom JVM would then require all your users to download that JVM as well.

更不用说拥有自定义 JVM 之后,所有用户也都需要下载该 JVM。

回答by Martin OConnor

You could use the CipherOutputStream and CipherInputStream to serialize Java objects to disk in an encrypted format. This may an option open for saving data.

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

回答by MBCook

Kosi2801 is pretty much right on. The only thing I can think of you could do is the following, but it's ugly.

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

  1. Ship a small standard JAR and an encrypted data file.
  2. When the JAR runs, it decrypts (some) of the encrypted data file into memory (like the directory of where data is in the JAR, basically a simple in-memory file system of pointer/length pairs)
  3. Set up your own class loader that, when called, gets the right encrypted bytes from the JAR (using the pseudo-FS table described in #2), decrypts it, and then loads the class data from there
  1. 发送一个小的标准 JAR 和一个加密的数据文件。
  2. 当 JAR 运行时,它将(一些)加密的数据文件解密到内存中(就像数据在 JAR 中的目录,基本上是一个简单的指针/长度对的内存文件系统)
  3. 设置您自己的类加载器,在调用时从 JAR 中获取正确的加密字节(使用 #2 中描述的伪 FS 表),对其进行解密,然后从那里加载类数据

This would let you load the classes. You could do the same thing (without the class loader) to load other resources.

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

While fun to implement (for those who like a challenge) there are a few problems with this:

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

  1. You'd need to be able to decrypt the stuff, so the user would either have to enter a password every time or something similar. If the JAR knows enough to decrypt it's self, then anyone can look at it and figure out how to decrypt things. This could be mitigated by contacting a known-good server over the Internet to ask for the decryption key (as long as you make that process secure). Of course this requires an active 'net connection any time someone wants to run the program.
  2. Everything ends up in memory. Without a custom JVM that handle tiny bits of encrypted byte code (as Cameron McKay mentioned) the classes will end up decrypted sitting in main memory at some point. Unless you rely on the OS to prevent other people from reading that memory, you've already lost the battle to anyone with a little time on their hands. Same issue for resources (such as images/fonts/etc) that you try to read out of some encrypted store.
  1. 您需要能够解密这些内容,因此用户必须每次都输入密码或类似的内容。如果 JAR 有足够的知识来解密它自己,那么任何人都可以查看它并弄清楚如何解密。这可以通过通过 Internet 联系已知良好的服务器以请求解密密钥来缓解(只要您确保该过程安全)。当然,只要有人想要运行该程序,这都需要一个活动的“网络连接”。
  2. 一切都在记忆中结束。如果没有一个自定义的 JVM 来处理加密字节码的微小位(正如 Cameron McKay 提到的),这些类最终会在某个时候被解密,位于主内存中。除非您依靠操作系统来阻止其他人读取该内存,否则您已经输给了任何时间有限的人。您尝试从某些加密存储中读取资源(例如图像/字体/等)的相同问题。

So you can give people the run-around and make things harder, but in the situation you've given all you can do is try to make it not worth the time the other person will have to invest.

所以你可以让人们跑来跑去,让事情变得更难,但在这种情况下,你所能做的就是努力让它不值得其他人投入的时间。

Software protection is tough, especially in something like Java that can easily be decompiled and can't alter it's own code like C/Assembly could. There is a reason some of the most expensive software out there requires hardware dongles or comes locked to a certain CPU or other hardware.

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

回答by paulmurray

In general, there is no way to do this in a secure fashion, if you want the app and its data to be self-contained. However, you can certainly encrypt the files and decript them with a key buried in the code. A determined hacker can get it, but if that's not what you are worried about, then fine. If you do this, remember that encypted data cannot be compressed, so compress first, then encrypt.

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

If you genuinely need the data to be secure (eg, confidential data), you will need to encrypt the data with a key and supply that key to the app my some external means, such as putting it on a thumbdrive and getting that to the user by means of a secure courier.

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

Another possibility it to make the data (or the key) available over SSL, and use a good authentication method to verify who your user is.

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

In general - it's not possible for any system to be perfectly secure, but it's also not nessesary. A system only needs to be secure enough to discourage the attackers that you think will be trying to crack it.

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

回答by Ivan Kinash

I agree with Kosi2801. Class file encryption is just imitation of security (see http://www.excelsior-usa.com/articles/java-obfuscators.html) Use of custom ClassLoader's can break the application, e.g. in Application Servers.

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

There is the better way: use encryption of String constants in a class files. The most of commercial obfuscators have this function, for example Allatori, Stringer Java Obfuscation Toolkit, Zelix KlassMaster, Smokescreen, DashO(super expensive). The Stringer Java Obfuscator has call context check and integrity control featureswhich makes protection really hard to hack.

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

The most secure way is to store and execute parts of bytecode on an external device like JavaCard.

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

N.B. I'm CEO at Licel LLC. Developer of Stringer Java Obfuscator.

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