如何避免安装“无限强度” 部署应用程序时的 JCE 策略文件?
我有一个使用 256 位 AES 加密的应用程序,Java 不支持该加密。 我知道为了让它正常工作,我在安全文件夹中安装了 JCE 无限强度 jar。 这对我作为开发人员来说很好,我可以安装它们。
我的问题是,由于此应用程序将被分发,最终用户很可能不会安装这些策略文件。 让最终用户下载这些只是为了使应用程序发挥作用并不是一个有吸引力的解决方案。
有没有办法让我的应用程序运行而不覆盖最终用户计算机上的文件? 第三方软件可以在不安装策略文件的情况下处理它吗? 或者只是从 JAR 中引用这些策略文件的方法?
I have an app that uses 256-bit AES encryption which is not supported by Java out of the box. I know to get this to function correctly I install the JCE unlimited strength jars in the security folder. This is fine for me being the developer, I can install them.
My question is since this app will be distributed, end users most likely will not have these policy files installed. Having the end user download these just to make the app function is not an attractive solution.
Is there a way to make my app run without overwriting files on the end user machine? A third party software that can handle it without the policy files installed? Or a way to just reference these policy files from within a JAR?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(11)
对于这个问题,有一些常见的解决方案。 不幸的是,这些都不是完全令人满意:
但是还有反射。有什么是你不能使用反射做的吗?
在执行任何加密操作之前,只需从静态初始化程序等调用
removeCryptographyRestrictions()
即可。JceSecurity.isRestricted = false
部分是直接使用 256 位密码所需的全部内容; 但是,如果没有其他两个操作,Cipher.getMaxAllowedKeyLength()
仍将继续报告 128,并且 256 位 TLS 密码套件将无法工作。此代码适用于 Oracle Java 7 和 8,并在 Java 9 和 OpenJDK 上自动跳过不需要的进程。 毕竟,这是一个丑陋的黑客行为,它可能无法在其他供应商的虚拟机上运行。
它也不适用于 Oracle Java 6,因为私有 JCE 类在那里被混淆了。 不过,混淆不会因版本而异,因此技术上仍然可以支持 Java 6。
There are a couple of commonly quoted solutions to this problem. Unfortunately neither of these are entirely satisfactory:
But then there's reflection. Is there anything you can't do using reflection?
Simply call
removeCryptographyRestrictions()
from a static initializer or such before performing any cryptographic operations.The
JceSecurity.isRestricted = false
part is all that is needed to use 256-bit ciphers directly; however, without the two other operations,Cipher.getMaxAllowedKeyLength()
will still keep reporting 128, and 256-bit TLS cipher suites won't work.This code works on Oracle Java 7 and 8, and automatically skips the process on Java 9 and OpenJDK where it's not needed. Being an ugly hack after all, it likely doesn't work on other vendors' VMs.
It also doesn't work on Oracle Java 6, because the private JCE classes are obfuscated there. The obfuscation does not change from version to version though, so it is still technically possible to support Java 6.
现在,Java 9 以及任何最新版本的 Java 6、7 或 8 都不再需要此功能。最后! :)
根据 JDK-8170157,现在默认启用无限制加密策略。
JIRA 问题的特定版本:
请注意,如果由于某种奇怪的原因Java 9 中需要旧的行为,可以使用以下方式设置:
This is now no longer needed for Java 9, nor for any recent release of Java 6, 7, or 8. Finally! :)
Per JDK-8170157, the unlimited cryptographic policy is now enabled by default.
Specific versions from the JIRA issue:
Note that if for some odd reason the old behavior is needed in Java 9, it can be set using:
这是解决方案:http://middlesphere-1。 blogspot.ru/2014/06/this-code-allows-to-break-limit-if.html
Here is solution: http://middlesphere-1.blogspot.ru/2014/06/this-code-allows-to-break-limit-if.html
从 JDK 8u102 开始,发布的依赖反射的解决方案将不再起作用:这些解决方案设置的字段现在是
final
(https://bugs.openjdk.java.net/browse/JDK-8149417)。看起来又回到了 (a) 使用 Bouncy Castle,或 (b) 安装 JCE 策略文件。
As of JDK 8u102, the posted solutions relying on reflection will no longer work: the field that these solutions set is now
final
(https://bugs.openjdk.java.net/browse/JDK-8149417).Looks like it's back to either (a) using Bouncy Castle, or (b) installing the JCE policy files.
据我所知,Bouncy Castle 仍然需要安装 jar。
我做了一个小测试,似乎证实了这一点:
http://www .bouncycastle.org/wiki/display/JA1/Frequently+Asked+Questions
Bouncy Castle still requires jars installed as far as I can tell.
I did a little test and it seemed to confirm this:
http://www.bouncycastle.org/wiki/display/JA1/Frequently+Asked+Questions
对于替代加密库,请查看 Bouncy Castle。 它具有 AES 和许多附加功能。 这是一个自由的开源库。 不过,您必须使用轻量级的专有 Bouncy Castle API 才能实现此功能。
For an alternative cryptography library, have a look at Bouncy Castle. It has AES and a lot of added functionality. It's a liberal open source library. You will have to use the lightweight, proprietary Bouncy Castle API for this to work though.
您可以使用方法
来测试可用的密钥长度,使用它并通知用户发生了什么。 例如,由于未安装策略文件,您的应用程序将回退到 128 位密钥。 具有安全意识的用户将安装策略文件,其他人将继续使用较弱的密钥。
You could use method
to test the available key length, use that and inform the user about what is going on. Something stating that your application is falling back to 128 bit keys due to the policy files not being installed, for example. Security conscious users will install the policy files, others will continue using weaker keys.
对于我们的应用程序,我们有一个客户端服务器架构,并且只允许在服务器级别解密/加密数据。 因此,仅在那里需要 JCE 文件。
我们遇到了另一个问题,我们需要通过 JNLP 更新客户端计算机上的安全 jar,它会在首次运行时覆盖
${java.home}/lib/security/
中的库和 JVM。这让它发挥作用。
For our application, we had a client server architecture and we only allowed decrypting/encrypting data in the server level. Hence the JCE files are only needed there.
We had another problem where we needed to update a security jar on the client machines, through JNLP, it overwrites the libraries in
${java.home}/lib/security/
and the JVM on first run.That made it work.
这是 ntoskrnl 答案的更新版本。
它还包含一个删除最终修饰符的函数,例如评论中提到的 Arjan 。
此版本适用于 JRE 8u111 或更高版本。
Here's a updated version of ntoskrnl answer.
It additionally contains a function to remove the final modifier like Arjan mentioned in the comments.
This version works with JRE 8u111 or newer.
以下是 @ntoskrnl 代码的修改版本,其中包含 检查的
isRestrictedCryptography
实际的 Cipher.getMaxAllowedKeyLength、slf4j 日志记录以及对应用程序引导程序的单例初始化的支持如下所示:当 Java 8u162 中默认使用 @cranphin 的无限策略时,此代码将正确地停止通过反射进行破坏答案预测。
Here is a modified version of @ntoskrnl's code featuring
isRestrictedCryptography
check by actualCipher.getMaxAllowedKeyLength
, slf4j logging and support of singleton initialization from application bootstrap like this:This code would correctly stop mangling with reflection when unlimited policy becomes available by default in Java 8u162 as @cranphin's answer predicts.
在安装程序期间,只需提示用户并下载 DOS 批处理脚本或 Bash shell 脚本并将 JCE 复制到正确的系统位置。
我曾经必须为服务器 Web 服务执行此操作,而不是正式的安装程序,我只是提供脚本来在用户运行应用程序之前设置应用程序。 您可以使应用程序无法运行,直到它们运行安装脚本。 您还可以让应用程序抱怨 JCE 丢失,然后要求下载并重新启动应用程序?
During installation of your program, just prompt the user and have a DOS Batch script or a Bash shell script download and copy the JCE into the proper system location.
I used to have to do this for a server webservice and instead of a formal installer, I just provided scripts to setup the app before the user could run it. You can make the app un-runnable until they run the setup script. You could also make the app complain that the JCE is missing and then ask to download and restart the app?