您好, 欢迎来到 !    登录 | 注册 | | 设为首页 | 收藏本站

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

Java部署应用程序时如何避免安装“ Unlimited Strength” 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:
         *
         * JceS@R_301_1360@.isRestricted = false;
         * JceS@R_301_1360@.defaultPolicy.perms.clear();
         * JceS@R_301_1360@.defaultPolicy.add(CryptoAllPermission.INSTANCE);
         */
        final Class<?> jceS@R_301_1360@ = Class.forName("javax.crypto.JceS@R_301_1360@");
        final Class<?> cryptoPermissions = Class.forName("javax.crypto.CryptoPermissions");
        final Class<?> cryptoAllPermission = Class.forName("javax.crypto.CryptoAllPermission");

        final Field isRestrictedField = jceS@R_301_1360@.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 = jceS@R_301_1360@.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()在执行任何加密操作之前,只需从静态初始化程序等调用即可。

JceS@R_301_1360@.isRestricted = false就是直接使用256位密码所需的全部内容。但是,如果没有其他两项操作,Cipher.getMaxAllowedKeyLength()仍将继续报告128个,而256位TLS密码套件将不起作用。

代码可在Oracle Java 7和8上运行,并在不需要的Java 9和OpenJDK上自动跳过该过程。毕竟是一个丑陋的黑客,它可能无法在其他供应商的VM上运行。

它在Oracle Java 6上也不起作用,因为私有JCE类在那里被混淆了。但是,各个版本之间的混淆并不会改变,因此从技术上讲,仍然可以支持Java 6。

分享改善这个答案

java 2022/1/1 18:21:51 有488人围观

撰写回答


你尚未登录,登录后可以

和开发者交流问题的细节

关注并接收问题和回答的更新提醒

参与内容的编辑和改进,让解决方法与时俱进

请先登录

推荐问题


联系我
置顶