如何避免安装“无限强度”部署应用程序时的JCE策略文件? [英] How to avoid installing "Unlimited Strength" JCE policy files when deploying an application?

查看:149
本文介绍了如何避免安装“无限强度”部署应用程序时的JCE策略文件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个使用256位AES加密的应用程序,Java不支持开箱即用。我知道要使其正常运行我在安全文件夹中安装JCE无限强度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.

有没有办法让我的应用运行而不会覆盖最终用户机器上的文件?可以在没有安装策略文件的情况下处理它的第三方软件?或者只是从JAR中引用这些策略文件的方法?

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?

推荐答案

这个问题有几个常用的引用解决方案。不幸的是,这些都不是完全令人满意的:

There are a couple of commonly quoted solutions to this problem. Unfortunately neither of these are entirely satisfactory:


  • 安装无限强度策略文件虽然这可能是您的开发工作站的正确解决方案,但它很快就成为让非技术用户在每台计算机上安装文件的主要麻烦(如果不是障碍)。 没办法用程序分发文件;它们必须安装在JRE目录中(由于权限,它甚至可能是只读的)。

  • 跳过JCE API 并使用另一个加密库,例如 Bouncy Castle 。这种方法需要额外的1MB库,这可能是一个很大的负担,具体取决于应用程序。复制标准库中包含的功能也很愚蠢。显然,API也与通常的JCE接口完全不同。 (BC确实实现了JCE提供程序,但这没有用,因为在移交给实现之前应用了密钥强度限制。)此解决方案也不允许您使用256位TLS( SSL)密码套件,因为标准TLS库在内部调用JCE来确定任何限制。

  • Install the unlimited strength policy files. While this is probably the right solution for your development workstation, it quickly becomes a major hassle (if not a roadblock) to have non-technical users install the files on every computer. There is no way to distribute the files with your program; they must be installed in the JRE directory (which may even be read-only due to permissions).
  • Skip the JCE API and use another cryptography library such as Bouncy Castle. This approach requires an extra 1MB library, which may be a significant burden depending on the application. It also feels silly to duplicate functionality included in the standard libraries. Obviously, the API is also completely different from the usual JCE interface. (BC does implement a JCE provider, but that doesn't help because the key strength restrictions are applied before handing over to the implementation.) This solution also won't let you use 256-bit TLS (SSL) cipher suites, because the standard TLS libraries call the JCE internally to determine any restrictions.

但是那时有反射。 你有什么不能用反射做的吗?

But then there's reflection. Is there anything you can't do using reflection?

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()在执行任何加密操作之前从静态初始化程序等。

Simply call removeCryptographyRestrictions() from a static initializer or such before performing any cryptographic operations.

JceSecurity.isRestricted = false 部分是直接使用256位密码所需的一切;但是,如果没有其他两个操作, Cipher.getMaxAllowedKeyLength()仍然会报告128,并且256位TLS密码套件将无法工作。

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.

此代码适用于Oracle Java 7和8,并自动跳过Java 9和OpenJDK上不需要的过程。毕竟,作为一个丑陋的黑客,它可能不适用于其他供应商的虚拟机。

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.

它也不适用于Oracle Java 6,因为私有JCE类在那里被混淆了。虽然混淆不会因版本而异,但从技术上讲,支持Java 6仍然是可能的。

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.

这篇关于如何避免安装“无限强度”部署应用程序时的JCE策略文件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆