我有一个使用256位AES加密的应用程序,Java开箱即用不支持。我知道要使其正常运行,我在security文件夹中安装了JCE不限强度的jars。作为开发人员,这对我来说很好,我可以安装它们。
我的问题是,由于将分发此应用程序,最终用户很可能不会安装这些策略文件。让最终用户下载这些文件只是为了使应用程序功能并不是一个有吸引力的解决方案。
有没有一种方法可以使我的应用程序运行而不会覆盖最终用户计算机上的文件?可以在不安装策略文件的情况下处理它的第三方软件?还是仅从JAR内引用这些策略文件的方法?
有两个通常引用的解决方案。不幸的是,这些都不是完全令人满意的:
安装无限强度策略文件。尽管这可能是适合您的开发工作站的解决方案,但让非技术用户在每台计算机上安装文件很快成为一个主要麻烦(如果不是障碍)。有没有办法来分发与您的程序文件; 它们必须安装在JRE目录中(由于权限的缘故,它甚至可能是只读的)。
跳过JCE API并使用另一个加密库,例如Bouncy Castle。这种方法需要额外的1MB库,根据应用程序的不同,这可能是一个很大的负担。复制标准库中包含的功能也很愚蠢。显然,API也与通常的JCE接口完全不同。(BC确实实现了JCE提供程序,但这无济于事,因为在移交给实现之前已应用了密钥强度限制。)该解决方案也不允许您使用256位TLS(SSL)密码套件,因为标准TLS库在内部调用JCE以确定任何限制。
但是然后有反思。有什么您不能使用反射来做的吗?
private static void removeCryptographyRestrictions() {
if (!isRestrictedCryptography()) {
logger.fine("Cryptography restrictions removal not needed");
return;
}
try {
/*
* Do the following, but with reflection to bypass access checks:
*
* JceSecurity.isRestricted = false;
* JceSecurity.defaultPolicy.perms.clear();
* JceSecurity.defaultPolicy.add(CryptoAllPermission.INSTANCE);
*/
final Class<?> jceSecurity = Class.forName("javax.crypto.JceSecurity");
final Class<?> cryptoPermissions = Class.forName("javax.crypto.CryptoPermissions");
final Class<?> cryptoAllPermission = Class.forName("javax.crypto.CryptoAllPermission");
final Field isRestrictedField = jceSecurity.getDeclaredField("isRestricted");
isRestrictedField.setAccessible(true);
final Field modifiersField = Field.class.getDeclaredField("modifiers");
modifiersField.setAccessible(true);
modifiersField.setInt(isRestrictedField, isRestrictedField.getModifiers() & ~Modifier.FINAL);
isRestrictedField.set(null, false);
final Field defaultPolicyField = jceSecurity.getDeclaredField("defaultPolicy");
defaultPolicyField.setAccessible(true);
final PermissionCollection defaultPolicy = (PermissionCollection) defaultPolicyField.get(null);
final Field perms = cryptoPermissions.getDeclaredField("perms");
perms.setAccessible(true);
((Map<?, ?>) perms.get(defaultPolicy)).clear();
final Field instance = cryptoAllPermission.getDeclaredField("INSTANCE");
instance.setAccessible(true);
defaultPolicy.add((Permission) instance.get(null));
logger.fine("Successfully removed cryptography restrictions");
} catch (final Exception e) {
logger.log(Level.WARNING, "Failed to remove cryptography restrictions", e);
}
}
private static boolean isRestrictedCryptography() {
// This matches Oracle Java 7 and 8, but not Java 9 or OpenJDK.
final String name = System.getProperty("java.runtime.name");
final String ver = System.getProperty("java.version");
return name != null && name.equals("Java(TM) SE Runtime Environment")
&& ver != null && (ver.startsWith("1.7") || ver.startsWith("1.8"));
}
removeCryptographyRestrictions()
在执行任何加密操作之前,只需从静态初始化程序等调用即可。
这JceSecurity.isRestricted = false
就是直接使用256位密码所需的全部内容。但是,如果没有其他两项操作,Cipher.getMaxAllowedKeyLength()
仍将继续报告128个,而256位TLS密码套件将不起作用。
该代码可在Oracle Java 7和8上运行,并在不需要的Java 9和OpenJDK上自动跳过该过程。毕竟是一个丑陋的骇客,它可能无法在其他供应商的VM上运行。
它在Oracle Java 6上也不起作用,因为私有JCE类在那里被混淆了。但是,混淆不会随版本而变化,因此从技术上讲,仍然可以支持Java 6。
问题内容: 我有一个使用256位AES加密的应用程序,Java开箱即用不支持。我知道要使其正常运行,我将JCE无限强度的jar安装在security文件夹中。作为开发人员,这对我来说很好,我可以安装它们。 我的问题是,由于将分发此应用程序,因此最终用户很可能不会安装这些策略文件。让最终用户下载这些文件只是为了使应用程序功能并不是一种有吸引力的解决方案。 有没有一种方法可以使我的应用程序运行而不会覆
问题内容: 我有一个使用256位AES加密的应用程序,Java开箱即用不支持。我知道要使其正常运行,我在security文件夹中安装了JCE不限强度的jars。作为开发人员,这对我来说很好,我可以安装它们。 我的问题是,由于将分发此应用程序,因此最终用户很可能不会安装这些策略文件。让最终用户下载这些文件只是为了使应用程序功能并不是一个有吸引力的解决方案。 有没有一种方法可以使我的应用程序运行而不会
问题内容: 有人可以向我解释如何安装无限强度管辖权策略文件。我从Oracle网站下载了.jar文件,但安装时遇到了问题。我正在制作的Java程序不断给我这个错误: 问题答案: 您需要确定Java主目录路径(通过Java或在命令行上)。它应该是如下路径: 在Windows上 在Mac OS X上 在* nix上 然后,您需要将下载的和文件复制到目录中:并覆盖同名的现有文件。 更新了05/17/17
问题内容: 我需要安装 Java加密扩展 为在/ 。原来,从步骤 自述 其附带的文件,安装程序只包括指令和,但不为/ 。我试图将JAR文件放入,但也没有用。您知道如何安装吗? 问题答案: 正如另一个答案和Oracle 针对Java 8 Update 161 的发行说明中所指出的那样,自从Update 161起,默认情况下将启用无限加密,并且如果使用此版本或更高版本的全新安装,则无需执行任何操作。
问题内容: 对于仅支持Java 8的服务器,它无法从cent OS建立安全的套接字连接 版 资源 使用相同版本的JVM,它可以在OSX上成功进行握手,在centOS上失败,失败原因是它仅尝试使用(JVM 8中的默认设置)并且不尝试使用较低的协议 调试说明: 题: 为什么可以在OSX而不是CentOS上进行选择? 如何告诉JVM按特定顺序使用协议,或者如果它考虑版本的顺序,那么我如何告诉JVM也尝试
有人能向我解释一下如何安装无限力量管辖权政策文件吗?我从甲骨文网站下载了. jar文件,但我在安装它们时遇到了问题。我正在制作Java程序一直给我这个错误: