当前位置: 首页 > 面试题库 >

Java部署应用程序时如何避免安装“ Unlimited Strength” JCE策略文件?

尚恩
2023-03-14
问题内容

我有一个使用256位AES加密的应用程序,Java开箱即用不支持。我知道要使其正常运行,我在security文件夹中安装了JCE不限强度的jars。作为开发人员,这对我来说很好,我可以安装它们。

我的问题是,由于将分发此应用程序,因此最终用户很可能不会安装这些策略文件。让最终用户下载这些文件只是为了使应用程序功能并不是一个有吸引力的解决方案。

有没有一种方法可以使我的应用程序运行而不会覆盖最终用户计算机上的文件?可以在不安装策略文件的情况下处理它的第三方软件?还是仅从JAR内引用这些策略文件的方法?


问题答案:

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

  • Install the unlimited strength policy files.。尽管这可能是适合你的开发工作站的解决方案,但要让非技术用户在每台计算机上安装文件,很快就会成为一个主要麻烦(如果不是障碍)。有没有办法来分发与你的程序文件; 它们必须安装在JRE目录中(由于权限的缘故,它甚至可能是只读的)。
  • Skip the 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。作为开发人员,这对我来说很好,我可以安装它们。 我的问题是,由于将分发此应用程序,最终用户很可能不会安装这些策略文件。让最终用户下载这些文件只是为了使应用程序功能并不是一个有吸引力的解决方案。 有没有一种方法可以使我的应用程序运行而不会覆盖

  • 问题内容: 我使用Spark Web框架创建了一个Web应用程序,但是我不知道如何部署该Web应用程序。很抱歉,如果这是非常基本的内容,但我是Spark框架的新手,找不到任何指导我如何部署Spark WebApp的文档。 如何独立部署Spark WebApp 如何构建spark webapp(用于war文件或此类文件)以及如何通过Web服务器(jetty或Tomcat)进行部署。 问题答案: 首先

  • 当在本地运行我的Angular应用程序时,我可以转到例如localhost:4200/login。然而,当我部署我的Angular应用程序时,当我转到website.com/login时,我会得到“在此服务器上找不到请求的URL/登录”。我的应用程序部署到Google Cloud AppEngine上。

  • 问题内容: Sun的PKCS11 JCE安全提供程序缺少我们需要的某些功能。 因此,我使用原始资源编写了它的增强版本。 不幸的是,JCE基础结构拒绝新的提供者 “ JCE无法验证提供者”, 因为它没有正确签名。 抛出。 (呼叫) 关于如何签署新提供商以使其与JCE一起工作的任何建议? 问题答案: 该过程在文档“如何实现 提供者”中进行了描述。 它涉及到电子邮件 太阳向Oracle提供一些信息(包括